• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without modification,
4  * are permitted provided that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain the above copyright notice, this list of
7  *    conditions and the following disclaimer.
8  *
9  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
10  *    of conditions and the following disclaimer in the documentation and/or other materials
11  *    provided with the distribution.
12  *
13  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14  *    to endorse or promote products derived from this software without specific prior written
15  *    permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "lwip/sockets.h"
31 #include "lwip/priv/tcpip_priv.h"
32 #include "lwip/priv/sockets_priv.h"
33 #include "lwip/prot/dhcp.h"
34 #include "lwip/dhcp.h"
35 #include "lwip/if_api.h"
36 
37 #if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL
38 
39 #include "lwip/distributed_net/udp_transmit.h"
40 
get_msg_data_len(const struct msghdr * hdr)41 static s32_t get_msg_data_len(const struct msghdr *hdr)
42 {
43   if (hdr->msg_iovlen > MAX_IOV_NUM) {
44     return -1;
45   }
46 
47   s32_t data_len = 0;
48   for (int i = 0; i < hdr->msg_iovlen; ++i) {
49     if (hdr->msg_iov[i].iov_len > MAX_UDP_PAYLOAD_LEN) {
50       set_errno(EMSGSIZE);
51       return -1;
52     }
53     data_len += (s32_t)hdr->msg_iov[i].iov_len;
54     if (data_len > MAX_UDP_PAYLOAD_LEN) {
55       set_errno(EMSGSIZE);
56       return -1;
57     }
58   }
59 
60   return data_len;
61 }
62 
udp_transmit_sendto(int sock,const void * buf,size_t buf_len,const struct sockaddr_in * dest_addr)63 ssize_t udp_transmit_sendto(int sock, const void *buf, size_t buf_len, const struct sockaddr_in *dest_addr)
64 {
65   if (buf_len > MAX_UDP_PAYLOAD_LEN) {
66     set_errno(EMSGSIZE);
67     return -1;
68   }
69 
70   udp_data data = {0};
71   (void)memset_s(&data, sizeof(data), 0, sizeof(data));
72   (void)strcpy_s(data.dest_addr, sizeof(data.dest_addr), inet_ntoa(dest_addr->sin_addr));
73   data.dest_port = ntohs(dest_addr->sin_port);
74 
75   struct iovec iov[2] = {0};
76   (void)memset_s(iov, sizeof(iov), 0, sizeof(iov));
77   iov[0].iov_base = (void *)&data;
78   iov[0].iov_len = sizeof(data);
79   iov[1].iov_base = (void *)buf;
80   iov[1].iov_len = buf_len;
81 
82   struct sockaddr_in transmit_addr = {0};
83   (void)memset_s(&transmit_addr, sizeof(transmit_addr), 0, sizeof(transmit_addr));
84   INIT_SOCK_ADDR(&transmit_addr, LOCAL_SERVER_IP, get_local_udp_server_port());
85 
86   struct msghdr send_hdr = {0};
87   (void)memset_s(&send_hdr, sizeof(send_hdr), 0, sizeof(send_hdr));
88   SET_MSG_ADDR(&send_hdr, &transmit_addr, sizeof(transmit_addr));
89   send_hdr.msg_iov = iov;
90   send_hdr.msg_iovlen = 2;
91 
92 #if LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG
93   return lwip_sendmsg_internal(sock, &send_hdr, 0);
94 #else
95   return lwip_sendmsg(sock, &send_hdr, 0);
96 #endif
97 }
98 
udp_transmit_sendmsg(int sock,const struct msghdr * hdr)99 ssize_t udp_transmit_sendmsg(int sock, const struct msghdr *hdr)
100 {
101   if (get_msg_data_len(hdr) < 0) {
102     return -1;
103   }
104 
105   struct sockaddr_in temp_addr_in = {0};
106   (void)memset_s(&temp_addr_in, sizeof(temp_addr_in), 0, sizeof(temp_addr_in));
107   (void)memcpy_s(&temp_addr_in, sizeof(temp_addr_in), hdr->msg_name, MIN(sizeof(temp_addr_in), hdr->msg_namelen));
108 
109   udp_data data = {0};
110   (void)memset_s(&data, sizeof(data), 0, sizeof(data));
111   (void)strcpy_s(data.dest_addr, sizeof(data.dest_addr), inet_ntoa(temp_addr_in.sin_addr));
112   data.dest_port = ntohs(temp_addr_in.sin_port);
113 
114   u32_t size = sizeof(struct iovec) * (hdr->msg_iovlen + 1);
115   struct iovec *iov = mem_malloc(size);
116   if (iov == NULL) {
117     set_errno(ENOMEM);
118     return -1;
119   }
120   (void)memset_s(iov, size, 0, size);
121   iov[0].iov_base = (void *)&data;
122   iov[0].iov_len = sizeof(data);
123   for (int i = 0; i < hdr->msg_iovlen; ++i) {
124     iov[i + 1].iov_base = hdr->msg_iov[i].iov_base;
125     iov[i + 1].iov_len = hdr->msg_iov[i].iov_len;
126   }
127 
128   struct sockaddr_in transmit_addr = {0};
129   (void)memset_s(&transmit_addr, sizeof(transmit_addr), 0, sizeof(transmit_addr));
130   INIT_SOCK_ADDR(&transmit_addr, LOCAL_SERVER_IP, get_local_udp_server_port());
131 
132   struct msghdr send_hdr = {0};
133   (void)memset_s(&send_hdr, sizeof(send_hdr), 0, sizeof(send_hdr));
134   SET_MSG_ADDR(&send_hdr, &transmit_addr, sizeof(transmit_addr));
135   send_hdr.msg_iov = iov;
136   send_hdr.msg_iovlen = hdr->msg_iovlen + 1;
137 
138 #if LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG
139   ssize_t ret = lwip_sendmsg_internal(sock, &send_hdr, 0);
140 #else
141   ssize_t ret = lwip_sendmsg(sock, &send_hdr, 0);
142 #endif
143   mem_free(iov);
144   return ret;
145 }
146 
147 #endif /* LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL */
148