• 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/opt.h"
31 
32 #if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL
33 
34 #include "lwip/distributed_net/udp_transmit.h"
35 
get_msg_data_len(const struct msghdr * hdr)36 static s32_t get_msg_data_len(const struct msghdr *hdr)
37 {
38   if (hdr->msg_iovlen > MAX_IOV_NUM) {
39     return -1;
40   }
41 
42   s32_t data_len = 0;
43   for (int i = 0; i < hdr->msg_iovlen; ++i) {
44     if (hdr->msg_iov[i].iov_len > MAX_UDP_PAYLOAD_LEN) {
45       set_errno(EMSGSIZE);
46       return -1;
47     }
48     data_len += (s32_t)hdr->msg_iov[i].iov_len;
49     if (data_len > MAX_UDP_PAYLOAD_LEN) {
50       set_errno(EMSGSIZE);
51       return -1;
52     }
53   }
54 
55   return data_len;
56 }
57 
udp_transmit_sendto(int sock,const void * buf,size_t buf_len,const struct sockaddr_in * dest_addr)58 ssize_t udp_transmit_sendto(int sock, const void *buf, size_t buf_len, const struct sockaddr_in *dest_addr)
59 {
60   if (buf_len > MAX_UDP_PAYLOAD_LEN) {
61     set_errno(EMSGSIZE);
62     return -1;
63   }
64 
65   udp_data data = {0};
66   (void)memset_s(&data, sizeof(data), 0, sizeof(data));
67   (void)strcpy_s(data.dest_addr, sizeof(data.dest_addr), inet_ntoa(dest_addr->sin_addr));
68   data.dest_port = ntohs(dest_addr->sin_port);
69 
70   struct iovec iov[2] = {0};
71   (void)memset_s(iov, sizeof(iov), 0, sizeof(iov));
72   iov[0].iov_base = (void *)&data;
73   iov[0].iov_len = sizeof(data);
74   iov[1].iov_base = (void *)buf;
75   iov[1].iov_len = buf_len;
76 
77   struct sockaddr_in transmit_addr = {0};
78   (void)memset_s(&transmit_addr, sizeof(transmit_addr), 0, sizeof(transmit_addr));
79   INIT_SOCK_ADDR(&transmit_addr, LOCAL_SERVER_IP, get_local_udp_server_port());
80 
81   struct msghdr send_hdr = {0};
82   (void)memset_s(&send_hdr, sizeof(send_hdr), 0, sizeof(send_hdr));
83   SET_MSG_ADDR(&send_hdr, &transmit_addr, sizeof(transmit_addr));
84   send_hdr.msg_iov = iov;
85   send_hdr.msg_iovlen = 2;
86 
87 #if LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG
88   return lwip_sendmsg_internal(sock, &send_hdr, 0);
89 #else
90   return lwip_sendmsg(sock, &send_hdr, 0);
91 #endif
92 }
93 
udp_transmit_sendmsg(int sock,const struct msghdr * hdr)94 ssize_t udp_transmit_sendmsg(int sock, const struct msghdr *hdr)
95 {
96   if (get_msg_data_len(hdr) < 0) {
97     return -1;
98   }
99 
100   struct sockaddr_in temp_addr_in = {0};
101   (void)memset_s(&temp_addr_in, sizeof(temp_addr_in), 0, sizeof(temp_addr_in));
102   (void)memcpy_s(&temp_addr_in, sizeof(temp_addr_in), hdr->msg_name, MIN(sizeof(temp_addr_in), hdr->msg_namelen));
103 
104   udp_data data = {0};
105   (void)memset_s(&data, sizeof(data), 0, sizeof(data));
106   (void)strcpy_s(data.dest_addr, sizeof(data.dest_addr), inet_ntoa(temp_addr_in.sin_addr));
107   data.dest_port = ntohs(temp_addr_in.sin_port);
108 
109   u32_t size = sizeof(struct iovec) * (hdr->msg_iovlen + 1);
110   struct iovec *iov = mem_malloc(size);
111   if (iov == NULL) {
112     set_errno(ENOMEM);
113     return -1;
114   }
115   (void)memset_s(iov, size, 0, size);
116   iov[0].iov_base = (void *)&data;
117   iov[0].iov_len = sizeof(data);
118   for (int i = 0; i < hdr->msg_iovlen; ++i) {
119     iov[i + 1].iov_base = hdr->msg_iov[i].iov_base;
120     iov[i + 1].iov_len = hdr->msg_iov[i].iov_len;
121   }
122 
123   struct sockaddr_in transmit_addr = {0};
124   (void)memset_s(&transmit_addr, sizeof(transmit_addr), 0, sizeof(transmit_addr));
125   INIT_SOCK_ADDR(&transmit_addr, LOCAL_SERVER_IP, get_local_udp_server_port());
126 
127   struct msghdr send_hdr = {0};
128   (void)memset_s(&send_hdr, sizeof(send_hdr), 0, sizeof(send_hdr));
129   SET_MSG_ADDR(&send_hdr, &transmit_addr, sizeof(transmit_addr));
130   send_hdr.msg_iov = iov;
131   send_hdr.msg_iovlen = hdr->msg_iovlen + 1;
132 
133 #if LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG
134   ssize_t ret = lwip_sendmsg_internal(sock, &send_hdr, 0);
135 #else
136   ssize_t ret = lwip_sendmsg(sock, &send_hdr, 0);
137 #endif
138   mem_free(iov);
139   return ret;
140 }
141 
142 #endif /* LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL */
143