Skip to content

Commit

Permalink
UDP backlog and prevent filtering of received messages in uIP
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JAndrassy committed Oct 11, 2020
1 parent a12aee1 commit f1b97b8
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The modernization includes:

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

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).

Expand Down
60 changes: 47 additions & 13 deletions src/EthernetUdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ UIPUDP::stop()
_uip_udp_conn->appstate = NULL;
_uip_udp_conn=NULL;
Enc28J60Network::freeBlock(appdata.packet_in);
Enc28J60Network::freeBlock(appdata.packet_next);
_flushBlocks(appdata.packet_next);
Enc28J60Network::freeBlock(appdata.packet_out);
memset(&appdata,0,sizeof(appdata));
}
Expand Down Expand Up @@ -212,8 +212,10 @@ UIPUDP::parsePacket()
#endif
Enc28J60Network::freeBlock(appdata.packet_in);

appdata.packet_in = appdata.packet_next;
appdata.packet_next = NOBLOCK;
appdata.packet_in = appdata.packet_next[0].packet;
uip_ipaddr_copy(appdata.remote_ip, appdata.packet_next[0].remote_ip);
appdata.remote_port = appdata.packet_next[0].remote_port;
_moveBlocks(appdata.packet_next);

#ifdef UIPETHERNET_DEBUG_UDP
if (appdata.packet_in != NOBLOCK)
Expand Down Expand Up @@ -301,14 +303,14 @@ UIPUDP::discardReceived()
IPAddress
UIPUDP::remoteIP()
{
return _uip_udp_conn ? ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress();
return ip_addr_uip(appdata.remote_ip);
}

// Return the port of the host who sent the current incoming packet
uint16_t
UIPUDP::remotePort()
{
return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0;
return ntohs(appdata.remote_port);
}

// uIP callback function
Expand All @@ -319,21 +321,22 @@ uipudp_appcall(void) {
{
if (uip_newdata())
{
if (data->packet_next == NOBLOCK)
uint8_t p = UIPUDP::_newBlock(data->packet_next);
if (data->packet_next[p].packet == NOBLOCK)
{
uip_udp_conn->rport = UDPBUF->srcport;
uip_ipaddr_copy(uip_udp_conn->ripaddr,UDPBUF->srcipaddr);
data->packet_next = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN);
data->packet_next[p].remote_port = UDPBUF->srcport;
uip_ipaddr_copy( data->packet_next[p].remote_ip,UDPBUF->srcipaddr);
data->packet_next[p].packet = Enc28J60Network::allocBlock(ntohs(UDPBUF->udplen)-UIP_UDPH_LEN);
//if we are unable to allocate memory the packet is dropped. udp doesn't guarantee packet delivery
if (data->packet_next != NOBLOCK)
if (data->packet_next[p].packet != NOBLOCK)
{
//discard Linklevel and IP and udp-header and any trailing bytes:
Enc28J60Network::copyPacket(data->packet_next,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next));
Enc28J60Network::copyPacket(data->packet_next[p].packet,0,UIPEthernetClass::in_packet,UIP_UDP_PHYH_LEN,Enc28J60Network::blockSize(data->packet_next[p].packet));
#ifdef UIPETHERNET_DEBUG_UDP
Serial.print(F("udp, uip_newdata received packet: "));
Serial.print(data->packet_next);
Serial.print(data->packet_next[p].packet);
Serial.print(F(", size: "));
Serial.println(Enc28J60Network::blockSize(data->packet_next));
Serial.println(Enc28J60Network::blockSize(data->packet_next[p].packet));
#endif
}
}
Expand Down Expand Up @@ -379,4 +382,35 @@ UIPUDP::_send(uip_udp_userdata_t *data) {
#endif
}
}

uint8_t
UIPUDP::_newBlock(uip_udp_msg_rec_t* block)
{
for (uint8_t i = 0; i < UIP_UDP_BACKLOG; i++)
{
if (block[i].packet == NOBLOCK)
return i;
}
return UIP_UDP_BACKLOG-1;
}

void
UIPUDP::_moveBlocks(uip_udp_msg_rec_t* block)
{
for (uint8_t i = 0; i < UIP_UDP_BACKLOG-1; i++)
{
block[i] = block[i+1];
}
block[UIP_UDP_BACKLOG-1].packet = NOBLOCK;
}

void
UIPUDP::_flushBlocks(uip_udp_msg_rec_t* block)
{
for (uint8_t i = 0; i < UIP_UDP_BACKLOG; i++)
{
Enc28J60Network::freeBlock(block[i].packet);
block[i].packet = NOBLOCK;
}
}
#endif
17 changes: 14 additions & 3 deletions src/EthernetUdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,20 @@ extern "C" {
#define UIP_UDP_PHYH_LEN UIP_LLH_LEN+UIP_IPUDPH_LEN
#define UIP_UDP_MAXPACKETSIZE UIP_UDP_MAXDATALEN+UIP_UDP_PHYH_LEN

typedef struct {
memhandle packet = NOBLOCK;
uip_ipaddr_t remote_ip;
uint16_t remote_port = 0;
} uip_udp_msg_rec_t;

typedef struct {
memaddress out_pos;
memhandle packet_next;
memhandle packet_in;
memhandle packet_out;
uip_udp_msg_rec_t packet_next[UIP_UDP_BACKLOG];
memhandle packet_in = NOBLOCK;
memhandle packet_out = NOBLOCK;
boolean send;
uip_ipaddr_t remote_ip;
uint16_t remote_port = 0;
} uip_udp_userdata_t;

class EthernetUDP : public UDP
Expand Down Expand Up @@ -123,6 +131,9 @@ class EthernetUDP : public UDP
friend class UIPEthernetClass;
static void _send(uip_udp_userdata_t *data);

static uint8_t _newBlock(uip_udp_msg_rec_t* blocks);
static void _moveBlocks(uip_udp_msg_rec_t* blocks);
static void _flushBlocks(uip_udp_msg_rec_t* blocks);
};

#endif
2 changes: 1 addition & 1 deletion src/utility/mempool_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef uint8_t memhandle;
#endif

#if UIP_UDP and UIP_UDP_CONNS
#define NUM_UDP_MEMBLOCKS 3*UIP_UDP_CONNS
#define NUM_UDP_MEMBLOCKS ((2+UIP_UDP_BACKLOG)*UIP_UDP_CONNS)
#else
#define NUM_UDP_MEMBLOCKS 0
#endif
Expand Down
11 changes: 10 additions & 1 deletion src/utility/uipethernet-conf.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef UIPETHERNET_CONF_H
#define UIPETHERNET_CONF_H

// https://github.com/jandrassy/EthernetENC/wiki/Settings

/* for TCP */
#ifndef UIP_SOCKET_NUMPACKETS
#define UIP_SOCKET_NUMPACKETS 3
Expand All @@ -15,7 +17,14 @@
#define UIP_CONF_UDP 1
#endif
#ifndef UIP_CONF_UDP_CONNS
#define UIP_CONF_UDP_CONNS 4
#define UIP_CONF_UDP_CONNS 2
#endif

/**
* size of received UDP messages backlog. it must be at least 1
*/
#ifndef UIP_UDP_BACKLOG
#define UIP_UDP_BACKLOG 2
#endif

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

0 comments on commit f1b97b8

Please sign in to comment.