Skip to content

Commit 1ba7e03

Browse files
authored
Merge pull request #21 from danielinux/fix-udp-recvfrom
Fix remote_ip not set in UDP recvfrom
2 parents 2fd11af + a7db693 commit 1ba7e03

2 files changed

Lines changed: 240 additions & 9 deletions

File tree

src/test/unit/unit.c

Lines changed: 227 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,219 @@ START_TEST(test_udp_sendto_and_recvfrom)
10351035
(struct wolfIP_sockaddr *)&from, &from_len);
10361036
ck_assert_int_eq(ret, (int)sizeof(payload));
10371037
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
1038-
ck_assert_uint_eq(from.sin_port, remote_port);
1038+
ck_assert_uint_eq(from.sin_port, ee16(remote_port));
1039+
}
1040+
END_TEST
1041+
1042+
START_TEST(test_udp_recvfrom_sets_remote_ip)
1043+
{
1044+
struct wolfIP s;
1045+
int sd;
1046+
struct wolfIP_sockaddr_in sin;
1047+
uint8_t payload[4] = {0xAA, 0xBB, 0xCC, 0xDD};
1048+
uint8_t rxbuf[4] = {0};
1049+
struct wolfIP_sockaddr_in from;
1050+
socklen_t from_len = sizeof(from);
1051+
int ret;
1052+
ip4 local_ip = 0x0A000001U;
1053+
ip4 remote_ip = 0x0A000002U;
1054+
uint16_t local_port = 4001;
1055+
uint16_t remote_port = 5001;
1056+
struct tsocket *ts;
1057+
1058+
wolfIP_init(&s);
1059+
mock_link_init(&s);
1060+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
1061+
1062+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1063+
ck_assert_int_gt(sd, 0);
1064+
1065+
memset(&sin, 0, sizeof(sin));
1066+
sin.sin_family = AF_INET;
1067+
sin.sin_port = ee16(local_port);
1068+
sin.sin_addr.s_addr = ee32(local_ip);
1069+
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
1070+
ck_assert_int_eq(ret, 0);
1071+
1072+
ts = &s.udpsockets[SOCKET_UNMARK(sd)];
1073+
ck_assert_uint_eq(ts->remote_ip, 0);
1074+
1075+
inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
1076+
payload, sizeof(payload));
1077+
1078+
memset(&from, 0, sizeof(from));
1079+
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
1080+
(struct wolfIP_sockaddr *)&from, &from_len);
1081+
ck_assert_int_eq(ret, (int)sizeof(payload));
1082+
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
1083+
ck_assert_uint_eq(from.sin_addr.s_addr, ee32(remote_ip));
1084+
ck_assert_uint_eq(ts->remote_ip, remote_ip);
1085+
}
1086+
END_TEST
1087+
1088+
START_TEST(test_udp_recvfrom_null_src_addr_len)
1089+
{
1090+
struct wolfIP s;
1091+
int sd;
1092+
struct wolfIP_sockaddr_in sin;
1093+
uint8_t payload[4] = {0x11, 0x22, 0x33, 0x44};
1094+
uint8_t rxbuf[4] = {0};
1095+
int ret;
1096+
ip4 local_ip = 0x0A000001U;
1097+
ip4 remote_ip = 0x0A000002U;
1098+
uint16_t local_port = 4002;
1099+
uint16_t remote_port = 5002;
1100+
1101+
wolfIP_init(&s);
1102+
mock_link_init(&s);
1103+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
1104+
1105+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1106+
ck_assert_int_gt(sd, 0);
1107+
1108+
memset(&sin, 0, sizeof(sin));
1109+
sin.sin_family = AF_INET;
1110+
sin.sin_port = ee16(local_port);
1111+
sin.sin_addr.s_addr = ee32(local_ip);
1112+
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
1113+
ck_assert_int_eq(ret, 0);
1114+
1115+
inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
1116+
payload, sizeof(payload));
1117+
1118+
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0, NULL, NULL);
1119+
ck_assert_int_eq(ret, (int)sizeof(payload));
1120+
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
1121+
}
1122+
END_TEST
1123+
1124+
START_TEST(test_udp_recvfrom_preserves_remote_ip)
1125+
{
1126+
struct wolfIP s;
1127+
int sd;
1128+
struct wolfIP_sockaddr_in sin;
1129+
uint8_t payload[4] = {0x55, 0x66, 0x77, 0x88};
1130+
uint8_t rxbuf[4] = {0};
1131+
struct wolfIP_sockaddr_in from;
1132+
socklen_t from_len = sizeof(from);
1133+
int ret;
1134+
ip4 local_ip = 0x0A000001U;
1135+
ip4 remote_ip = 0x0A000002U;
1136+
ip4 preset_remote_ip = 0x0A000099U;
1137+
uint16_t local_port = 4003;
1138+
uint16_t remote_port = 5003;
1139+
struct tsocket *ts;
1140+
1141+
wolfIP_init(&s);
1142+
mock_link_init(&s);
1143+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
1144+
1145+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1146+
ck_assert_int_gt(sd, 0);
1147+
1148+
memset(&sin, 0, sizeof(sin));
1149+
sin.sin_family = AF_INET;
1150+
sin.sin_port = ee16(local_port);
1151+
sin.sin_addr.s_addr = ee32(local_ip);
1152+
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
1153+
ck_assert_int_eq(ret, 0);
1154+
1155+
ts = &s.udpsockets[SOCKET_UNMARK(sd)];
1156+
ts->remote_ip = preset_remote_ip;
1157+
1158+
inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
1159+
payload, sizeof(payload));
1160+
1161+
memset(&from, 0, sizeof(from));
1162+
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
1163+
(struct wolfIP_sockaddr *)&from, &from_len);
1164+
ck_assert_int_eq(ret, (int)sizeof(payload));
1165+
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
1166+
ck_assert_uint_eq(from.sin_addr.s_addr, ee32(remote_ip));
1167+
ck_assert_uint_eq(ts->remote_ip, preset_remote_ip);
1168+
}
1169+
END_TEST
1170+
1171+
START_TEST(test_udp_recvfrom_null_addrlen)
1172+
{
1173+
struct wolfIP s;
1174+
int sd;
1175+
struct wolfIP_sockaddr_in sin;
1176+
uint8_t payload[4] = {0x9A, 0xBC, 0xDE, 0xF0};
1177+
uint8_t rxbuf[4] = {0};
1178+
struct wolfIP_sockaddr_in from;
1179+
int ret;
1180+
ip4 local_ip = 0x0A000001U;
1181+
ip4 remote_ip = 0x0A000002U;
1182+
uint16_t local_port = 4004;
1183+
uint16_t remote_port = 5004;
1184+
1185+
wolfIP_init(&s);
1186+
mock_link_init(&s);
1187+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
1188+
1189+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1190+
ck_assert_int_gt(sd, 0);
1191+
1192+
memset(&sin, 0, sizeof(sin));
1193+
sin.sin_family = AF_INET;
1194+
sin.sin_port = ee16(local_port);
1195+
sin.sin_addr.s_addr = ee32(local_ip);
1196+
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
1197+
ck_assert_int_eq(ret, 0);
1198+
1199+
inject_udp_datagram(&s, TEST_PRIMARY_IF, remote_ip, local_ip, remote_port, local_port,
1200+
payload, sizeof(payload));
1201+
1202+
memset(&from, 0, sizeof(from));
1203+
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
1204+
(struct wolfIP_sockaddr *)&from, NULL);
1205+
ck_assert_int_eq(ret, -WOLFIP_EINVAL);
1206+
}
1207+
END_TEST
1208+
1209+
START_TEST(test_udp_recvfrom_src_equals_local_ip_does_not_persist_remote)
1210+
{
1211+
struct wolfIP s;
1212+
int sd;
1213+
struct wolfIP_sockaddr_in sin;
1214+
uint8_t payload[4] = {0x01, 0x02, 0x03, 0x04};
1215+
uint8_t rxbuf[4] = {0};
1216+
struct wolfIP_sockaddr_in from;
1217+
socklen_t from_len = sizeof(from);
1218+
int ret;
1219+
ip4 local_ip = 0x0A000001U;
1220+
uint16_t local_port = 4005;
1221+
uint16_t remote_port = 5005;
1222+
struct tsocket *ts;
1223+
1224+
wolfIP_init(&s);
1225+
mock_link_init(&s);
1226+
wolfIP_ipconfig_set(&s, local_ip, 0xFFFFFF00U, 0);
1227+
1228+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1229+
ck_assert_int_gt(sd, 0);
1230+
1231+
memset(&sin, 0, sizeof(sin));
1232+
sin.sin_family = AF_INET;
1233+
sin.sin_port = ee16(local_port);
1234+
sin.sin_addr.s_addr = ee32(local_ip);
1235+
ret = wolfIP_sock_bind(&s, sd, (struct wolfIP_sockaddr *)&sin, sizeof(sin));
1236+
ck_assert_int_eq(ret, 0);
1237+
1238+
ts = &s.udpsockets[SOCKET_UNMARK(sd)];
1239+
ck_assert_uint_eq(ts->remote_ip, 0);
1240+
1241+
inject_udp_datagram(&s, TEST_PRIMARY_IF, local_ip, local_ip, remote_port, local_port,
1242+
payload, sizeof(payload));
1243+
1244+
memset(&from, 0, sizeof(from));
1245+
ret = wolfIP_sock_recvfrom(&s, sd, rxbuf, sizeof(rxbuf), 0,
1246+
(struct wolfIP_sockaddr *)&from, &from_len);
1247+
ck_assert_int_eq(ret, (int)sizeof(payload));
1248+
ck_assert_mem_eq(rxbuf, payload, sizeof(payload));
1249+
ck_assert_uint_eq(from.sin_addr.s_addr, ee32(local_ip));
1250+
ck_assert_uint_eq(ts->remote_ip, 0);
10391251
}
10401252
END_TEST
10411253

@@ -1449,13 +1661,13 @@ START_TEST(test_sock_recvfrom_short_addrlen)
14491661
ck_assert_int_gt(udp_sd, 0);
14501662
alen = (socklen_t)1;
14511663
ck_assert_int_eq(wolfIP_sock_recvfrom(&s, udp_sd, buf, sizeof(buf), 0,
1452-
(struct wolfIP_sockaddr *)&sin, &alen), -1);
1664+
(struct wolfIP_sockaddr *)&sin, &alen), -WOLFIP_EINVAL);
14531665

14541666
icmp_sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_ICMP);
14551667
ck_assert_int_gt(icmp_sd, 0);
14561668
alen = (socklen_t)1;
14571669
ck_assert_int_eq(wolfIP_sock_recvfrom(&s, icmp_sd, buf, sizeof(buf), 0,
1458-
(struct wolfIP_sockaddr *)&sin, &alen), -1);
1670+
(struct wolfIP_sockaddr *)&sin, &alen), -WOLFIP_EINVAL);
14591671
}
14601672
END_TEST
14611673
START_TEST(test_dns_query_and_callback_a)
@@ -4275,7 +4487,7 @@ START_TEST(test_sock_recvfrom_udp_short_addrlen)
42754487
ck_assert_int_gt(udp_sd, 0);
42764488

42774489
ck_assert_int_eq(wolfIP_sock_recvfrom(&s, udp_sd, buf, sizeof(buf), 0,
4278-
(struct wolfIP_sockaddr *)&sin, &alen), -1);
4490+
(struct wolfIP_sockaddr *)&sin, &alen), -WOLFIP_EINVAL);
42794491
}
42804492
END_TEST
42814493

@@ -4294,7 +4506,7 @@ START_TEST(test_sock_recvfrom_icmp_short_addrlen)
42944506
ck_assert_int_gt(icmp_sd, 0);
42954507

42964508
ck_assert_int_eq(wolfIP_sock_recvfrom(&s, icmp_sd, buf, sizeof(buf), 0,
4297-
(struct wolfIP_sockaddr *)&sin, &alen), -1);
4509+
(struct wolfIP_sockaddr *)&sin, &alen), -WOLFIP_EINVAL);
42984510
}
42994511
END_TEST
43004512

@@ -12082,6 +12294,16 @@ Suite *wolf_suite(void)
1208212294
suite_add_tcase(s, tc_proto);
1208312295
tcase_add_test(tc_proto, test_udp_sendto_and_recvfrom);
1208412296
suite_add_tcase(s, tc_proto);
12297+
tcase_add_test(tc_proto, test_udp_recvfrom_sets_remote_ip);
12298+
suite_add_tcase(s, tc_proto);
12299+
tcase_add_test(tc_proto, test_udp_recvfrom_null_src_addr_len);
12300+
suite_add_tcase(s, tc_proto);
12301+
tcase_add_test(tc_proto, test_udp_recvfrom_preserves_remote_ip);
12302+
suite_add_tcase(s, tc_proto);
12303+
tcase_add_test(tc_proto, test_udp_recvfrom_null_addrlen);
12304+
suite_add_tcase(s, tc_proto);
12305+
tcase_add_test(tc_proto, test_udp_recvfrom_src_equals_local_ip_does_not_persist_remote);
12306+
suite_add_tcase(s, tc_proto);
1208512307
tcase_add_test(tc_proto, test_dns_query_and_callback_a);
1208612308
suite_add_tcase(s, tc_proto);
1208712309
tcase_add_test(tc_proto, test_dhcp_parse_offer_and_ack);

src/wolfip.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,17 +2647,24 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in
26472647
if (SOCKET_UNMARK(sockfd) >= MAX_UDPSOCKETS)
26482648
return -WOLFIP_EINVAL;
26492649
ts = &s->udpsockets[SOCKET_UNMARK(sockfd)];
2650+
if (sin && !addrlen)
2651+
return -WOLFIP_EINVAL;
26502652
if (sin && *addrlen < sizeof(struct wolfIP_sockaddr_in))
2651-
return -1;
2653+
return -WOLFIP_EINVAL;
26522654
if (addrlen) *addrlen = sizeof(struct wolfIP_sockaddr_in);
26532655
if (fifo_len(&ts->sock.udp.rxbuf) == 0)
26542656
return -WOLFIP_EAGAIN;
26552657
desc = fifo_peek(&ts->sock.udp.rxbuf);
26562658
udp = (struct wolfIP_udp_datagram *)(ts->rxmem + desc->pos + sizeof(*desc));
2659+
if (ts->remote_ip == 0) {
2660+
ip4 src_ip = ee32(udp->ip.src);
2661+
if (src_ip != ts->local_ip)
2662+
ts->remote_ip = src_ip;
2663+
}
26572664
if (sin) {
26582665
sin->sin_family = AF_INET;
2659-
sin->sin_port = ee16(udp->src_port);
2660-
sin->sin_addr.s_addr = ee32(ts->remote_ip);
2666+
sin->sin_port = udp->src_port;
2667+
sin->sin_addr.s_addr = udp->ip.src;
26612668
}
26622669
seg_len = ee16(udp->len) - UDP_HEADER_LEN;
26632670
if (seg_len > len)
@@ -2670,8 +2677,10 @@ int wolfIP_sock_recvfrom(struct wolfIP *s, int sockfd, void *buf, size_t len, in
26702677
if (SOCKET_UNMARK(sockfd) >= MAX_ICMPSOCKETS)
26712678
return -WOLFIP_EINVAL;
26722679
ts = &s->icmpsockets[SOCKET_UNMARK(sockfd)];
2680+
if (sin && !addrlen)
2681+
return -WOLFIP_EINVAL;
26732682
if (sin && *addrlen < sizeof(struct wolfIP_sockaddr_in))
2674-
return -1;
2683+
return -WOLFIP_EINVAL;
26752684
if (addrlen)
26762685
*addrlen = sizeof(struct wolfIP_sockaddr_in);
26772686
desc = fifo_peek(&ts->sock.udp.rxbuf);

0 commit comments

Comments
 (0)