mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-05-18 22:26:41 +08:00
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:
@@ -286,6 +286,8 @@ netconn_peer(struct netconn *conn, struct ip_addr **addr,
|
||||
case NETCONN_UDPLITE:
|
||||
case NETCONN_UDPNOCHKSUM:
|
||||
case NETCONN_UDP:
|
||||
if ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0)
|
||||
return -1;
|
||||
*addr = &(conn->pcb.udp->remote_ip);
|
||||
*port = conn->pcb.udp->remote_port;
|
||||
break;
|
||||
@@ -345,6 +347,7 @@ netconn_bind(struct netconn *conn, struct ip_addr *addr,
|
||||
memp_freep(MEMP_API_MSG, msg);
|
||||
return conn->err;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
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);
|
||||
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
|
||||
netconn_listen(struct netconn *conn)
|
||||
|
||||
@@ -71,7 +71,6 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if(conn->recvmbox != SYS_MBOX_NULL) {
|
||||
buf = memp_mallocp(MEMP_NETBUF);
|
||||
if(buf == NULL) {
|
||||
@@ -370,6 +369,26 @@ do_connect(struct api_msg_msg *msg)
|
||||
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
|
||||
do_listen(struct api_msg_msg *msg)
|
||||
@@ -524,6 +543,7 @@ static api_msg_decode decode[API_MSG_MAX] = {
|
||||
do_delconn,
|
||||
do_bind,
|
||||
do_connect,
|
||||
do_disconnect,
|
||||
do_listen,
|
||||
do_accept,
|
||||
do_send,
|
||||
|
||||
@@ -172,11 +172,14 @@ lwip_connect(int s, struct sockaddr *name, int namelen)
|
||||
if(sock == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
|
||||
remote_port = ((struct sockaddr_in *)name)->sin_port;
|
||||
|
||||
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
|
||||
|
||||
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_port = ((struct sockaddr_in *)name)->sin_port;
|
||||
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
|
||||
}
|
||||
|
||||
if(err != ERR_OK) {
|
||||
/* errno = ... */
|
||||
@@ -343,7 +346,7 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
|
||||
struct lwip_socket *sock;
|
||||
struct ip_addr remote_addr, *addr;
|
||||
u16_t remote_port, port;
|
||||
int ret;
|
||||
int ret,connected;
|
||||
|
||||
sock = get_socket(s);
|
||||
if(sock == NULL) {
|
||||
@@ -351,7 +354,7 @@ lwip_sendto(int s, void *data, int size, unsigned int flags,
|
||||
}
|
||||
|
||||
/* 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_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
|
||||
of the connection */
|
||||
netconn_connect(sock->conn, addr, port);
|
||||
if (connected)
|
||||
netconn_connect(sock->conn, addr, port);
|
||||
else
|
||||
netconn_disconnect(sock->conn);
|
||||
return ret;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user