sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most of the netconn_peer and netconn_addr processing is done inside tcpip_thread context in do_getaddr.

This commit is contained in:
fbernon 2007-11-12 22:39:24 +00:00
parent 8020ba2dc5
commit a4d14722f3
6 changed files with 95 additions and 97 deletions

View File

@ -460,6 +460,11 @@ HISTORY
++ Bug fixes: ++ Bug fixes:
2007-11-12 Frédéric Bernon
* sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most
of the netconn_peer and netconn_addr processing is done inside tcpip_thread
context in do_getaddr.
2007-11-10 Simon Goldschmidt 2007-11-10 Simon Goldschmidt
* etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can
happen any time). Now the packet simply isn't enqueued when out of memory. happen any time). Now the packet simply isn't enqueued when out of memory.

View File

@ -179,93 +179,32 @@ netconn_type(struct netconn *conn)
} }
/** /**
* Get the current perr a netconn is connected to. * Get the local or remote IP address and port of a netconn.
* This might only be temporary for UDP netconns,
* doesn't work for RAW netconns and returns garbage
* if called for a TCP listen netconn.
*
* @param conn the netconn to query
* @param addr a pointer to which to save the remote IP address
* @param port a pointer to which to save the remote port
* @return ERR_CONN for invalid connections
* ERR_OK if the information was retrieved
*/
err_t
netconn_peer(struct netconn *conn, struct ip_addr *addr, u16_t *port)
{
LWIP_ERROR("netconn_peer: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_peer: invalid addr", (addr != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_peer: invalid port", (port != NULL), return ERR_ARG;);
/* Not a good safe-thread protection, will be improved */
if (conn->pcb.ip == NULL)
return ERR_CONN;
*addr = conn->pcb.ip->remote_ip;
switch (NETCONNTYPE_GROUP(conn->type)) {
#if LWIP_RAW
case NETCONN_RAW:
/* return an error as connecting is only a helper for upper layers */
return ERR_CONN;
#endif /* LWIP_RAW */
#if LWIP_UDP
case NETCONN_UDP:
if ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0)
return ERR_CONN;
*port = conn->pcb.udp->remote_port;
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case NETCONN_TCP:
*port = conn->pcb.tcp->remote_port;
break;
#endif /* LWIP_TCP */
}
return ERR_OK;
}
/**
* Get the local IP address and port of a netconn.
* For RAW netconns, this returns the protocol instead of a port! * For RAW netconns, this returns the protocol instead of a port!
* *
* @param conn the netconn to query * @param conn the netconn to query
* @param addr a pointer to which to save the local IP address * @param addr a pointer to which to save the IP address
* @param port a pointer to which to save the local port (or protocol for RAW) * @param port a pointer to which to save the port (or protocol for RAW)
* @return ERR_CONN for invalid connections * @return ERR_CONN for invalid connections
* ERR_OK if the information was retrieved * ERR_OK if the information was retrieved
*/ */
err_t err_t
netconn_addr(struct netconn *conn, struct ip_addr *addr, u16_t *port) netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local)
{ {
LWIP_ERROR("netconn_addr: invalid conn", (conn != NULL), return ERR_ARG;); struct api_msg msg;
LWIP_ERROR("netconn_addr: invalid addr", (addr != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_addr: invalid port", (port != NULL), return ERR_ARG;);
/* Not a good safe-thread protection, will be improved */ LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
if (conn->pcb.ip == NULL) LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
return ERR_CONN; LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
*addr = conn->pcb.ip->local_ip; msg.function = do_getaddr;
msg.msg.conn = conn;
msg.msg.msg.ad.ipaddr = addr;
msg.msg.msg.ad.port = port;
msg.msg.msg.ad.local = local;
TCPIP_APIMSG(&msg);
switch (NETCONNTYPE_GROUP(conn->type)) { return conn->err;
#if LWIP_RAW
case NETCONN_RAW:
*port = conn->pcb.raw->protocol;
break;
#endif /* LWIP_RAW */
#if LWIP_UDP
case NETCONN_UDP:
*port = conn->pcb.udp->local_port;
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case NETCONN_TCP:
*port = conn->pcb.tcp->local_port;
break;
#endif /* LWIP_TCP */
}
return ERR_OK;
} }
/** /**
@ -346,7 +285,6 @@ netconn_disconnect(struct netconn *conn)
msg.msg.conn = conn; msg.msg.conn = conn;
TCPIP_APIMSG(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }
/** /**
@ -575,7 +513,6 @@ netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t apiflags
but if it is, this is done inside api_msg.c:do_write(), so we can use the but if it is, this is done inside api_msg.c:do_write(), so we can use the
non-blocking version here. */ non-blocking version here. */
TCPIP_APIMSG(&msg); TCPIP_APIMSG(&msg);
return conn->err; return conn->err;
} }

View File

@ -888,6 +888,54 @@ do_write(struct api_msg_msg *msg)
TCPIP_APIMSG_ACK(msg); TCPIP_APIMSG_ACK(msg);
} }
/**
* Return a connection's local or remote address
* Called from netconn_getaddr
*
* @param msg the api_msg_msg pointing to the connection
*/
void
do_getaddr(struct api_msg_msg *msg)
{
if (msg->conn->pcb.ip != NULL) {
*(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip);
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
case NETCONN_RAW:
if (msg->msg.ad.local) {
*(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
} else {
/* return an error as connecting is only a helper for upper layers */
msg->conn->err = ERR_CONN;
}
break;
#endif /* LWIP_RAW */
#if LWIP_UDP
case NETCONN_UDP:
if (msg->msg.ad.local) {
*(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
} else {
if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
msg->conn->err = ERR_CONN;
} else {
*(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
}
}
break;
#endif /* LWIP_UDP */
#if LWIP_TCP
case NETCONN_TCP:
*(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);
break;
#endif /* LWIP_TCP */
}
} else {
msg->conn->err =ERR_CONN;
}
TCPIP_APIMSG_ACK(msg);
}
/** /**
* Close a TCP pcb contained in a netconn * Close a TCP pcb contained in a netconn
* Called from netconn_close * Called from netconn_close
@ -942,3 +990,4 @@ do_join_leave_group(struct api_msg_msg *msg)
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
#endif /* LWIP_NETCONN */ #endif /* LWIP_NETCONN */

View File

@ -967,8 +967,7 @@ lwip_shutdown(int s, int how)
} }
static int static int
lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
err_t (* netconn_addrfunc)(struct netconn *conn, struct ip_addr *addr, u16_t *port))
{ {
struct lwip_socket *sock; struct lwip_socket *sock;
struct sockaddr_in sin; struct sockaddr_in sin;
@ -983,7 +982,7 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen,
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
/* get the IP address and port */ /* get the IP address and port */
netconn_addrfunc(sock->conn, &naddr, &sin.sin_port); netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
ip_addr_debug_print(SOCKETS_DEBUG, &naddr); ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
@ -1003,13 +1002,13 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen,
int int
lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
{ {
return lwip_getaddrname(s, name, namelen, netconn_peer); return lwip_getaddrname(s, name, namelen, 0);
} }
int int
lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
{ {
return lwip_getaddrname(s, name, namelen, netconn_addr); return lwip_getaddrname(s, name, namelen, 1);
} }
int int

View File

@ -148,29 +148,31 @@ netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
void (*callback)(struct netconn *, enum netconn_evt, u16_t len)); void (*callback)(struct netconn *, enum netconn_evt, u16_t len));
err_t netconn_delete (struct netconn *conn); err_t netconn_delete (struct netconn *conn);
enum netconn_type netconn_type (struct netconn *conn); enum netconn_type netconn_type (struct netconn *conn);
err_t netconn_peer (struct netconn *conn,
struct ip_addr *addr, err_t netconn_getaddr (struct netconn *conn,
u16_t *port); struct ip_addr *addr,
err_t netconn_addr (struct netconn *conn, u16_t *port,
struct ip_addr *addr, u8_t local);
u16_t *port); #define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
err_t netconn_bind (struct netconn *conn, err_t netconn_bind (struct netconn *conn,
struct ip_addr *addr, struct ip_addr *addr,
u16_t port); u16_t port);
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_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);
err_t netconn_sendto (struct netconn *conn, err_t netconn_sendto (struct netconn *conn,
struct netbuf *buf, struct ip_addr *addr, u16_t port); struct netbuf *buf, struct ip_addr *addr, u16_t port);
err_t netconn_send (struct netconn *conn, err_t netconn_send (struct netconn *conn,
struct netbuf *buf); struct netbuf *buf);
err_t netconn_write (struct netconn *conn, err_t netconn_write (struct netconn *conn,
const void *dataptr, int size, const void *dataptr, int size,
u8_t apiflags); u8_t apiflags);
err_t netconn_close (struct netconn *conn); err_t netconn_close (struct netconn *conn);
#if LWIP_IGMP #if LWIP_IGMP

View File

@ -58,6 +58,11 @@ struct api_msg_msg {
struct ip_addr *ipaddr; struct ip_addr *ipaddr;
u16_t port; u16_t port;
} bc; /* do_bind, do_connect */ } bc; /* do_bind, do_connect */
struct {
struct ip_addr *ipaddr;
u16_t *port;
u8_t local;
} ad; /* do_getaddr */
struct { struct {
const void *dataptr; const void *dataptr;
int len; int len;
@ -90,6 +95,7 @@ void do_listen ( struct api_msg_msg *msg);
void do_send ( struct api_msg_msg *msg); void do_send ( struct api_msg_msg *msg);
void do_recv ( struct api_msg_msg *msg); void do_recv ( struct api_msg_msg *msg);
void do_write ( struct api_msg_msg *msg); void do_write ( struct api_msg_msg *msg);
void do_getaddr ( struct api_msg_msg *msg);
void do_close ( struct api_msg_msg *msg); void do_close ( struct api_msg_msg *msg);
#if LWIP_IGMP #if LWIP_IGMP
void do_join_leave_group( struct api_msg_msg *msg); void do_join_leave_group( struct api_msg_msg *msg);