Skip to content

Commit f1b97b8

Browse files
committed
UDP backlog and prevent filtering of received messages in uIP
The IP address and port of received UDP message were stored in uIP record, but if these are set, uIP filters the incoming messages to match the IP and port.
1 parent a12aee1 commit f1b97b8

File tree

5 files changed

+73
-19
lines changed

5 files changed

+73
-19
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The modernization includes:
1515

1616
Limitations:
1717
* UDP.beginMulticast is not supported, because the uIP stack doesn't support multicast
18-
* UDB broadcasts receiving is turned off on ENC to lower the processing load on the library
18+
* UDP broadcasts receiving is turned off on ENC to lower the processing load on the library
1919

2020
This library doesn't have examples, because examples of the Arduino Ethernet library apply. You can find them in the Arduino IDE Examples menu Ethernet section. Only change `#include <Ethernet.h>` to `#include <EthernetENC.h>`. Some examples require [a little change](https://github.com/jandrassy/EthernetENC/wiki/Examples).
2121

src/EthernetUdp.cpp

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ UIPUDP::stop()
6767
_uip_udp_conn->appstate = NULL;
6868
_uip_udp_conn=NULL;
6969
Enc28J60Network::freeBlock(appdata.packet_in);
70-
Enc28J60Network::freeBlock(appdata.packet_next);
70+
_flushBlocks(appdata.packet_next);
7171
Enc28J60Network::freeBlock(appdata.packet_out);
7272
memset(&appdata,0,sizeof(appdata));
7373
}
@@ -212,8 +212,10 @@ UIPUDP::parsePacket()
212212
#endif
213213
Enc28J60Network::freeBlock(appdata.packet_in);
214214

215-
appdata.packet_in = appdata.packet_next;
216-
appdata.packet_next = NOBLOCK;
215+
appdata.packet_in = appdata.packet_next[0].packet;
216+
uip_ipaddr_copy(appdata.remote_ip, appdata.packet_next[0].remote_ip);
217+
appdata.remote_port = appdata.packet_next[0].remote_port;
218+
_moveBlocks(appdata.packet_next);
217219

218220
#ifdef UIPETHERNET_DEBUG_UDP
219221
if (appdata.packet_in != NOBLOCK)
@@ -301,14 +303,14 @@ UIPUDP::discardReceived()
301303
IPAddress
302304
UIPUDP::remoteIP()
303305
{
304-
return _uip_udp_conn ? ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress();
306+
return ip_addr_uip(appdata.remote_ip);
305307
}
306308

307309
// Return the port of the host who sent the current incoming packet
308310
uint16_t
309311
UIPUDP::remotePort()
310312
{
311-
return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0;
313+
return ntohs(appdata.remote_port);
312314
}
313315

314316
// uIP callback function
@@ -319,21 +321,22 @@ uipudp_appcall(void) {
319321
{
320322
if (uip_newdata())
321323
{
322-
if (data->packet_next == NOBLOCK)
324+
uint8_t p = UIPUDP::_newBlock(data->packet_next);
325+
if (data->packet_next[p].packet == NOBLOCK)
323326
{
324-
uip_udp_conn->rport = UDPBUF->srcport;
325-
uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr);
326-
data->packet_next = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN);
327+
data->packet_next[p].remote_port = UDPBUF->srcport;
328+
uip_ipaddr_copy( data->packet_next[p].remote_ip,UDPBUF->srcipaddr);
329+
data->packet_next[p].packet = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN);
327330
//if we are unable to allocate memory the packet is dropped. udp doesn't guarantee packet delivery
328-
if (data->packet_next != NOBLOCK)
331+
if (data->packet_next[p].packet != NOBLOCK)
329332
{
330333
//discard Linklevel and IP and udp-header and any trailing bytes:
331-
Enc28J60Network::copyPacket(data->packet_next,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next));
334+
Enc28J60Network::copyPacket(data->packet_next[p].packet,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next[p].packet));
332335
#ifdef UIPETHERNET_DEBUG_UDP
333336
Serial.print(F("udp, uip_newdata received packet: "));
334-
Serial.print(data->packet_next);
337+
Serial.print(data->packet_next[p].packet);
335338
Serial.print(F(", size: "));
336-
Serial.println(Enc28J60Network::blockSize(data->packet_next));
339+
Serial.println(Enc28J60Network::blockSize(data->packet_next[p].packet));
337340
#endif
338341
}
339342
}
@@ -379,4 +382,35 @@ UIPUDP::_send(uip_udp_userdata_t *data) {
379382
#endif
380383
}
381384
}
385+
386+
uint8_t
387+
UIPUDP::_newBlock(uip_udp_msg_rec_t* block)
388+
{
389+
for (uint8_t i = 0; i < UIP_UDP_BACKLOG; i++)
390+
{
391+
if (block[i].packet == NOBLOCK)
392+
return i;
393+
}
394+
return UIP_UDP_BACKLOG-1;
395+
}
396+
397+
void
398+
UIPUDP::_moveBlocks(uip_udp_msg_rec_t* block)
399+
{
400+
for (uint8_t i = 0; i < UIP_UDP_BACKLOG-1; i++)
401+
{
402+
block[i] = block[i+1];
403+
}
404+
block[UIP_UDP_BACKLOG-1].packet = NOBLOCK;
405+
}
406+
407+
void
408+
UIPUDP::_flushBlocks(uip_udp_msg_rec_t* block)
409+
{
410+
for (uint8_t i = 0; i < UIP_UDP_BACKLOG; i++)
411+
{
412+
Enc28J60Network::freeBlock(block[i].packet);
413+
block[i].packet = NOBLOCK;
414+
}
415+
}
382416
#endif

src/EthernetUdp.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,20 @@ extern "C" {
3131
#define UIP_UDP_PHYH_LEN UIP_LLH_LEN+UIP_IPUDPH_LEN
3232
#define UIP_UDP_MAXPACKETSIZE UIP_UDP_MAXDATALEN+UIP_UDP_PHYH_LEN
3333

34+
typedef struct {
35+
memhandle packet = NOBLOCK;
36+
uip_ipaddr_t remote_ip;
37+
uint16_t remote_port = 0;
38+
} uip_udp_msg_rec_t;
39+
3440
typedef struct {
3541
memaddress out_pos;
36-
memhandle packet_next;
37-
memhandle packet_in;
38-
memhandle packet_out;
42+
uip_udp_msg_rec_t packet_next[UIP_UDP_BACKLOG];
43+
memhandle packet_in = NOBLOCK;
44+
memhandle packet_out = NOBLOCK;
3945
boolean send;
46+
uip_ipaddr_t remote_ip;
47+
uint16_t remote_port = 0;
4048
} uip_udp_userdata_t;
4149

4250
class EthernetUDP : public UDP
@@ -123,6 +131,9 @@ class EthernetUDP : public UDP
123131
friend class UIPEthernetClass;
124132
static void _send(uip_udp_userdata_t *data);
125133

134+
static uint8_t _newBlock(uip_udp_msg_rec_t* blocks);
135+
static void _moveBlocks(uip_udp_msg_rec_t* blocks);
136+
static void _flushBlocks(uip_udp_msg_rec_t* blocks);
126137
};
127138

128139
#endif

src/utility/mempool_conf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef uint8_t memhandle;
1717
#endif
1818

1919
#if UIP_UDP and UIP_UDP_CONNS
20-
#define NUM_UDP_MEMBLOCKS 3*UIP_UDP_CONNS
20+
#define NUM_UDP_MEMBLOCKS ((2+UIP_UDP_BACKLOG)*UIP_UDP_CONNS)
2121
#else
2222
#define NUM_UDP_MEMBLOCKS 0
2323
#endif

src/utility/uipethernet-conf.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef UIPETHERNET_CONF_H
22
#define UIPETHERNET_CONF_H
33

4+
// https://github.com/jandrassy/EthernetENC/wiki/Settings
5+
46
/* for TCP */
57
#ifndef UIP_SOCKET_NUMPACKETS
68
#define UIP_SOCKET_NUMPACKETS 3
@@ -15,7 +17,14 @@
1517
#define UIP_CONF_UDP 1
1618
#endif
1719
#ifndef UIP_CONF_UDP_CONNS
18-
#define UIP_CONF_UDP_CONNS 4
20+
#define UIP_CONF_UDP_CONNS 2
21+
#endif
22+
23+
/**
24+
* size of received UDP messages backlog. it must be at least 1
25+
*/
26+
#ifndef UIP_UDP_BACKLOG
27+
#define UIP_UDP_BACKLOG 2
1928
#endif
2029

2130
/* timeout in ms for attempts to get a free memory block to write

0 commit comments

Comments
 (0)