Fix udp_bind to allow rebind for same socket (yesterday's commit broke that) and introduce connection info for UDP pcbs.New function netconn_disconnect, do_disconnect for deatching UDP from a remote addres.Fix #2240

This commit is contained in:
jani 2003-01-22 16:18:05 +00:00
parent 16434f0d01
commit 46c575c038
8 changed files with 87 additions and 23 deletions

View File

@ -286,6 +286,8 @@ netconn_peer(struct netconn *conn, struct ip_addr **addr,
case NETCONN_UDPLITE: case NETCONN_UDPLITE:
case NETCONN_UDPNOCHKSUM: case NETCONN_UDPNOCHKSUM:
case NETCONN_UDP: case NETCONN_UDP:
if ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0)
return -1;
*addr = &(conn->pcb.udp->remote_ip); *addr = &(conn->pcb.udp->remote_ip);
*port = conn->pcb.udp->remote_port; *port = conn->pcb.udp->remote_port;
break; break;
@ -345,6 +347,7 @@ netconn_bind(struct netconn *conn, struct ip_addr *addr,
memp_freep(MEMP_API_MSG, msg); memp_freep(MEMP_API_MSG, msg);
return conn->err; return conn->err;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
err_t err_t
netconn_connect(struct netconn *conn, struct ip_addr *addr, netconn_connect(struct netconn *conn, struct ip_addr *addr,
@ -375,6 +378,26 @@ netconn_connect(struct netconn *conn, struct ip_addr *addr,
memp_freep(MEMP_API_MSG, msg); memp_freep(MEMP_API_MSG, msg);
return conn->err; return conn->err;
} }
err_t
netconn_disconnect(struct netconn *conn)
{
struct api_msg *msg;
if(conn == NULL) {
return ERR_VAL;
}
if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
return ERR_MEM;
}
msg->type = API_MSG_DISCONNECT;
msg->msg.conn = conn;
api_msg_post(msg);
memp_freep(MEMP_API_MSG, msg);
return conn->err;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
err_t err_t
netconn_listen(struct netconn *conn) netconn_listen(struct netconn *conn)

View File

@ -71,7 +71,6 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
pbuf_free(p); pbuf_free(p);
return; return;
} }
if(conn->recvmbox != SYS_MBOX_NULL) { if(conn->recvmbox != SYS_MBOX_NULL) {
buf = memp_mallocp(MEMP_NETBUF); buf = memp_mallocp(MEMP_NETBUF);
if(buf == NULL) { if(buf == NULL) {
@ -370,6 +369,26 @@ do_connect(struct api_msg_msg *msg)
break; break;
} }
} }
static void
do_disconnect(struct api_msg_msg *msg)
{
switch(msg->conn->type) {
#if LWIP_UDP
case NETCONN_UDPLITE:
/* FALLTHROUGH */
case NETCONN_UDPNOCHKSUM:
/* FALLTHROUGH */
case NETCONN_UDP:
udp_disconnect(msg->conn->pcb.udp);
break;
#endif
case NETCONN_TCP:
break;
}
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void static void
do_listen(struct api_msg_msg *msg) do_listen(struct api_msg_msg *msg)
@ -524,6 +543,7 @@ static api_msg_decode decode[API_MSG_MAX] = {
do_delconn, do_delconn,
do_bind, do_bind,
do_connect, do_connect,
do_disconnect,
do_listen, do_listen,
do_accept, do_accept,
do_send, do_send,

View File

@ -173,10 +173,13 @@ lwip_connect(int s, struct sockaddr *name, int namelen)
return -1; return -1;
} }
if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {
err = netconn_disconnect(sock->conn);
} else {
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)name)->sin_port; remote_port = ((struct sockaddr_in *)name)->sin_port;
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
}
if(err != ERR_OK) { if(err != ERR_OK) {
/* errno = ... */ /* errno = ... */
@ -343,7 +346,7 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
struct lwip_socket *sock; struct lwip_socket *sock;
struct ip_addr remote_addr, *addr; struct ip_addr remote_addr, *addr;
u16_t remote_port, port; u16_t remote_port, port;
int ret; int ret,connected;
sock = get_socket(s); sock = get_socket(s);
if(sock == NULL) { if(sock == NULL) {
@ -351,7 +354,7 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
} }
/* get the peer if currently connected */ /* get the peer if currently connected */
netconn_peer(sock->conn, &addr, &port); connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);
remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
remote_port = ((struct sockaddr_in *)to)->sin_port; remote_port = ((struct sockaddr_in *)to)->sin_port;
@ -361,7 +364,10 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
/* reset the remote address and port number /* reset the remote address and port number
of the connection */ of the connection */
if (connected)
netconn_connect(sock->conn, addr, port); netconn_connect(sock->conn, addr, port);
else
netconn_disconnect(sock->conn);
return ret; return ret;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -28,7 +28,7 @@
* *
* Author: Adam Dunkels <adam@sics.se> * Author: Adam Dunkels <adam@sics.se>
* *
* $Id: udp.c,v 1.10 2003/01/21 14:09:31 jani Exp $ * $Id: udp.c,v 1.11 2003/01/22 16:18:05 jani Exp $
*/ */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -199,16 +199,15 @@ udp_input(struct pbuf *p, struct netif *inp)
break; break;
} }
} }
/* no fully matching pcb found? */ /* no fully matching pcb found? then look for an unconnected pcb */
if(pcb == NULL) { if(pcb == NULL) {
/* Iterate through the UDP pcb list for a pcb that matches /* Iterate through the UDP pcb list for a pcb that matches
the local address. */ the local address. */
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n", DEBUGF(UDP_DEBUG, ("udp_input: pcb local port %d (dgram %d)\n",
pcb->local_port, dest)); pcb->local_port, dest));
if(pcb->local_port == dest && if((pcb->flags & UDP_FLAGS_CONNECTED) == 0 &&
(ip_addr_isany(&pcb->remote_ip) || pcb->local_port == dest &&
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) || (ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) { ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break; break;
@ -396,13 +395,14 @@ err_t
udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{ {
struct udp_pcb *ipcb; struct udp_pcb *ipcb;
u8_t rebind = 0;
/* Insert UDP PCB into the list of active UDP PCBs. */ /* Check for double bind and rebind of the same pcb */
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
if (pcb == ipcb) { if (pcb == ipcb) {
/* Already on the list, just return. */ rebind = 1;
return ERR_OK; break;
} } else
if (ipcb->local_port == port) { if (ipcb->local_port == port) {
if(ip_addr_isany(&(ipcb->local_ip)) || if(ip_addr_isany(&(ipcb->local_ip)) ||
ip_addr_isany(ipaddr) || ip_addr_isany(ipaddr) ||
@ -416,9 +416,11 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
ip_addr_set(&pcb->local_ip, ipaddr); ip_addr_set(&pcb->local_ip, ipaddr);
pcb->local_port = port; pcb->local_port = port;
/* We need to place the PCB on the list. */ /* We need to place the PCB on the list if not already there. */
if (rebind == 0) {
pcb->next = udp_pcbs; pcb->next = udp_pcbs;
udp_pcbs = pcb; udp_pcbs = pcb;
}
DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %d\n", port)); DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %d\n", port));
return ERR_OK; return ERR_OK;
@ -430,6 +432,7 @@ udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
struct udp_pcb *ipcb; struct udp_pcb *ipcb;
ip_addr_set(&pcb->remote_ip, ipaddr); ip_addr_set(&pcb->remote_ip, ipaddr);
pcb->remote_port = port; pcb->remote_port = port;
pcb->flags |= UDP_FLAGS_CONNECTED;
/* Insert UDP PCB into the list of active UDP PCBs. */ /* Insert UDP PCB into the list of active UDP PCBs. */
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
@ -443,6 +446,12 @@ udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
udp_pcbs = pcb; udp_pcbs = pcb;
return ERR_OK; return ERR_OK;
} }
void
udp_disconnect(struct udp_pcb *pcb)
{
pcb->flags &= ~UDP_FLAGS_CONNECTED;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void void
udp_recv(struct udp_pcb *pcb, udp_recv(struct udp_pcb *pcb,
@ -474,6 +483,7 @@ struct udp_pcb *
udp_new(void) { udp_new(void) {
struct udp_pcb *pcb; struct udp_pcb *pcb;
pcb = memp_malloc(MEMP_UDP_PCB); pcb = memp_malloc(MEMP_UDP_PCB);
pcb->flags = 0;
if(pcb != NULL) { if(pcb != NULL) {
memset(pcb, 0, sizeof(struct udp_pcb)); memset(pcb, 0, sizeof(struct udp_pcb));
return pcb; return pcb;

View File

@ -122,6 +122,7 @@ err_t netconn_bind (struct netconn *conn,
err_t netconn_connect (struct netconn *conn, err_t netconn_connect (struct netconn *conn,
struct ip_addr *addr, struct ip_addr *addr,
u16_t port); u16_t port);
err_t netconn_disconnect (struct netconn *conn);
err_t netconn_listen (struct netconn *conn); err_t netconn_listen (struct netconn *conn);
struct netconn * netconn_accept (struct netconn *conn); struct netconn * netconn_accept (struct netconn *conn);
struct netbuf * netconn_recv (struct netconn *conn); struct netbuf * netconn_recv (struct netconn *conn);

View File

@ -49,6 +49,7 @@ enum api_msg_type {
API_MSG_BIND, API_MSG_BIND,
API_MSG_CONNECT, API_MSG_CONNECT,
API_MSG_DISCONNECT,
API_MSG_LISTEN, API_MSG_LISTEN,
API_MSG_ACCEPT, API_MSG_ACCEPT,

View File

@ -56,6 +56,7 @@ struct sockaddr {
#define SOCK_STREAM 1 #define SOCK_STREAM 1
#define SOCK_DGRAM 2 #define SOCK_DGRAM 2
#define AF_UNSPEC 0
#define AF_INET 2 #define AF_INET 2
#define PF_INET AF_INET #define PF_INET AF_INET

View File

@ -51,6 +51,7 @@ struct udp_hdr {
#define UDP_FLAGS_NOCHKSUM 0x01 #define UDP_FLAGS_NOCHKSUM 0x01
#define UDP_FLAGS_UDPLITE 0x02 #define UDP_FLAGS_UDPLITE 0x02
#define UDP_FLAGS_CONNECTED 0x04
struct udp_pcb { struct udp_pcb {
struct udp_pcb *next; struct udp_pcb *next;
@ -74,6 +75,7 @@ err_t udp_bind (struct udp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port); u16_t port);
err_t udp_connect (struct udp_pcb *pcb, struct ip_addr *ipaddr, err_t udp_connect (struct udp_pcb *pcb, struct ip_addr *ipaddr,
u16_t port); u16_t port);
void udp_disconnect (struct udp_pcb *pcb);
void udp_recv (struct udp_pcb *pcb, void udp_recv (struct udp_pcb *pcb,
void (* recv)(void *arg, struct udp_pcb *upcb, void (* recv)(void *arg, struct udp_pcb *upcb,
struct pbuf *p, struct pbuf *p,