Basic server functionality: listen(), accept()

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@382 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-11-16 18:48:39 +00:00
parent 5ea5c4cf09
commit 5d7b5add5d
20 changed files with 173 additions and 126 deletions

View File

@ -223,6 +223,7 @@
* Corrected a TCP problem where packets were dropped because there was no
recv() in place but the packet was being ACKed. There are still TCP
recv buffering issues, but this is part of a larger buffering issue.
* Basic server functionality verified: listen(), accept()

View File

@ -679,6 +679,7 @@ Other memory:
* Corrected a TCP problem where packets were dropped because there was no
recv() in place but the packet was being ACKed. There are still TCP
recv buffering issues, but this is part of a larger buffering issue.
* Basic server functionality verified: listen(), accept()
</pre></ul>
<table width ="100%">

View File

@ -293,6 +293,8 @@ CONFIG_NET_RESOLV_ENTRIES=4
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_SERVER=n
CONFIG_EXAMPLE_NETTEST_PERFORMANCE=n
CONFIG_EXAMPLE_NETTEST_IPADDR=(10<<24|0<<16|0<<8|2)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(10<<24|0<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)

View File

@ -294,6 +294,8 @@ CONFIG_NET_RESOLV_ENTRIES=4
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_SERVER=n
CONFIG_EXAMPLE_NETTEST_PERFORMANCE=n
CONFIG_EXAMPLE_NETTEST_IPADDR=(10<<24|0<<16|0<<8|2)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(10<<24|0<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)

View File

@ -267,6 +267,8 @@ CONFIG_EXAMPLE_UIP_DHCPC=y
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_SERVER=n
CONFIG_EXAMPLE_NETTEST_PERFORMANCE=n
CONFIG_EXAMPLE_NETTEST_IPADDR=(192<<24|168<<16|0<<8|128)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(192<<24|168<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)

View File

@ -268,6 +268,8 @@ CONFIG_EXAMPLE_UIP_DHCPC=y
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_SERVER=n
CONFIG_EXAMPLE_NETTEST_PERFORMANCE=n
CONFIG_EXAMPLE_NETTEST_IPADDR=(192<<24|168<<16|0<<8|128)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(192<<24|168<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)

View File

@ -1258,8 +1258,6 @@ static void dm9x_polltimer(int argc, uint32 arg, ...)
{
struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)arg;
dbg("Poll timer expiration\n");
/* If the number of contiguous RX packets exceeds a threshold, reset the counter and
* re-enable RX interrupts
*/

View File

@ -42,7 +42,7 @@ TARG_ASRCS =
TARG_AOBJS = $(TARG_ASRCS:.S=$(OBJEXT))
TARG_CSRCS = nettest.c
ifeq ($(CONFIG_NETTEST_SERVER),y)
ifeq ($(CONFIG_EXAMPLE_NETTEST_SERVER),y)
TARG_CSRCS += nettest-server.c
else
TARG_CSRCS += nettest-client.c
@ -55,13 +55,14 @@ TARG_OBJS = $(TARG_AOBJS) $(TARG_COBJS)
TARG_BIN = lib$(CONFIG_EXAMPLE)$(LIBEXT)
HOSTCFLAGS += -DCONFIG_NETTEST_HOST=1
ifeq ($(CONFIG_NETTEST_SERVER),y)
HOSTCFLAGS += -DCONFIG_NETTEST_SERVER=1
HOSTCFLAGS += -DCONFIG_EXAMPLE_NETTEST_HOST=1
ifeq ($(CONFIG_EXAMPLE_NETTEST_SERVER),y)
HOSTCFLAGS += -DCONFIG_EXAMPLE_NETTEST_SERVER=1 \
-DCONFIG_EXAMPLE_NETTEST_CLIENTIP="$(CONFIG_EXAMPLE_NETTEST_CLIENTIP)"
endif
HOST_SRCS = host.c
ifeq ($(CONFIG_NETTEST_SERVER),y)
ifeq ($(CONFIG_EXAMPLE_NETTEST_SERVER),y)
HOST_SRCS += nettest-client.c
else
HOST_SRCS += nettest-server.c

View File

@ -53,7 +53,7 @@
int main(int argc, char **argv, char **envp)
{
#ifdef CONFIG_NETTEST_SERVER
#ifdef CONFIG_EXAMPLE_NETTEST_SERVER
send_client();
#else
recv_server();

View File

@ -57,12 +57,12 @@ void send_client(void)
{
struct sockaddr_in myaddr;
char outbuf[SENDSIZE];
#ifndef CONFIG_NETTEST_PERFORMANCE
#ifndef CONFIG_EXAMPLE_NETTEST_PERFORMANCE
char inbuf[SENDSIZE];
#endif
int sockfd;
int nbytessent;
#ifndef CONFIG_NETTEST_PERFORMANCE
#ifndef CONFIG_EXAMPLE_NETTEST_PERFORMANCE
int nbytesrecvd;
#endif
int ch;
@ -107,7 +107,7 @@ void send_client(void)
}
}
#ifdef CONFIG_NETTEST_PERFORMANCE
#ifdef CONFIG_EXAMPLE_NETTEST_PERFORMANCE
/* Then receive messages forever */
for (;;)

View File

@ -63,7 +63,7 @@ void recv_server(void)
int acceptsd;
socklen_t addrlen;
int nbytesread;
#ifndef CONFIG_NETTEST_PERFORMANCE
#ifndef CONFIG_EXAMPLE_NETTEST_PERFORMANCE
int totalbytesread;
int nbytessent;
int ch;
@ -133,7 +133,7 @@ void recv_server(void)
}
#endif
#ifdef CONFIG_NETTEST_PERFORMANCE
#ifdef CONFIG_EXAMPLE_NETTEST_PERFORMANCE
/* Then receive data forever */
for (;;)
@ -194,7 +194,7 @@ void recv_server(void)
}
}
#ifdef CONFIG_NETTEST_HOST
#ifdef CONFIG_EXAMPLE_NETTEST_HOST
/* At present, data received by the target before it is completed the
* the write opertion and started the read operation results in a failure
* (the data is not received, but it is ACKed). This will have to be

View File

@ -94,7 +94,7 @@ int user_start(int argc, char *argv[])
addr.s_addr = HTONL(CONFIG_EXAMPLE_NETTEST_NETMASK);
uip_setnetmask("eth0", &addr);
#ifdef CONFIG_NETTEST_SERVER
#ifdef CONFIG_EXAMPLE_NETTEST_SERVER
recv_server();
#else
send_client();

View File

@ -40,7 +40,7 @@
* Included Files
****************************************************************************/
#ifdef CONFIG_NETTEST_HOST
#ifdef CONFIG_EXAMPLE_NETTEST_HOST
#else
# include <debug.h>
#endif
@ -49,7 +49,7 @@
* Definitions
****************************************************************************/
#ifdef CONFIG_NETTEST_HOST
#ifdef CONFIG_EXAMPLE_NETTEST_HOST
/* HTONS/L macros are unique to uIP */
# define HTONS(a) htons(a)

View File

@ -65,27 +65,27 @@
#define UIP_ACKDATA (1 << 0) /* Signifies that the outstanding data was acked and the
* application should send out new data instead of retransmitting
* the last data. */
#define UIP_NEWDATA (1 << 1) /* Flags the fact that the peer has sent us new data. */
* the last data */
#define UIP_NEWDATA (1 << 1) /* Flags the fact that the peer has sent us new data */
#define UIP_REXMIT (1 << 2) /* Tells the application to retransmit the data that was last
* sent. */
* sent */
#define UIP_POLL (1 << 3) /* Used for polling the application, to check if the application
* has data that it wants to send. */
* has data that it wants to send */
#define UIP_CLOSE (1 << 4) /* The remote host has closed the connection, thus the connection
* has gone away. Or the application signals that it wants to
* close the connection. */
* close the connection */
#define UIP_ABORT (1 << 5) /* The remote host has aborted the connection, thus the connection
* has gone away. Or the application signals that it wants to
* abort the connection. */
* abort the connection */
#define UIP_CONNECTED (1 << 6) /* We have got a connection from a remote host and have set up a
* new connection for it, or an active connection has been
* successfully established. */
#define UIP_TIMEDOUT (1 << 7) /* The connection has been aborted due to too many retransmissions. */
* successfully established */
#define UIP_TIMEDOUT (1 << 7) /* The connection has been aborted due to too many retransmissions */
#define UIP_DATA_EVENTS (UIP_ACKDATA|UIP_NEWDATA|UIP_REXMIT|UIP_POLL)
#define UIP_CONN_EVENTS (UIP_CLOSE|UIP_ABORT|UIP_CONNECTED|UIP_TIMEDOUT)
/* The TCP states used in the struct uip_conn tcpstateflags field. */
/* The TCP states used in the struct uip_conn tcpstateflags field */
#define UIP_CLOSED 0 /* The connection is not in use and available */
#define UIP_ALLOCATED 1 /* The connection is allocated, but not yet initialized */
@ -137,7 +137,7 @@
* Public Type Definitions
****************************************************************************/
/* Repressentation of an IP address. */
/* Repressentation of an IP address */
typedef in_addr_t uip_ip4addr_t;
typedef uint16 uip_ip6addr_t[8];
@ -161,26 +161,27 @@ struct uip_driver_s; /* Forward reference */
struct uip_conn
{
dq_entry_t node; /* Implements a doubly linked list */
uip_ipaddr_t ripaddr; /* The IP address of the remote host. */
uint16 lport; /* The local TCP port, in network byte order. */
uint16 rport; /* The local remote TCP port, in network byte order. */
uip_ipaddr_t lipaddr; /* The local IP address */
uip_ipaddr_t ripaddr; /* The IP address of the remote host */
uint16 lport; /* The local TCP port, in network byte order */
uint16 rport; /* The remoteTCP port, in network byte order */
uint8 rcv_nxt[4]; /* The sequence number that we expect to
* receive next. */
uint8 snd_nxt[4]; /* The sequence number that was last sent by us. */
uint16 len; /* Length of the data that was previously sent. */
* receive next */
uint8 snd_nxt[4]; /* The sequence number that was last sent by us */
uint16 len; /* Length of the data that was previously sent */
uint16 mss; /* Current maximum segment size for the
* connection. */
* connection */
uint16 initialmss; /* Initial maximum segment size for the
* connection. */
* connection */
uint8 sa; /* Retransmission time-out calculation state
* variable. */
* variable */
uint8 sv; /* Retransmission time-out calculation state
* variable. */
uint8 rto; /* Retransmission time-out. */
uint8 tcpstateflags; /* TCP state and flags. */
uint8 timer; /* The retransmission timer (units: half-seconds). */
* variable */
uint8 rto; /* Retransmission time-out */
uint8 tcpstateflags; /* TCP state and flags */
uint8 timer; /* The retransmission timer (units: half-seconds) */
uint8 nrtx; /* The number of retransmissions for the last
* segment sent. */
* segment sent */
/* Higher level logic can retain application specific information
* in the following:
@ -212,15 +213,15 @@ struct uip_conn
};
#ifdef CONFIG_NET_UDP
/* Representation of a uIP UDP connection. */
/* Representation of a uIP UDP connection */
struct uip_udp_conn
{
dq_entry_t node; /* Implements a doubly linked list */
uip_ipaddr_t ripaddr; /* The IP address of the remote peer. */
uint16 lport; /* The local port number in network byte order. */
uint16 rport; /* The remote port number in network byte order. */
uint8 ttl; /* Default time-to-live. */
uip_ipaddr_t ripaddr; /* The IP address of the remote peer */
uint16 lport; /* The local port number in network byte order */
uint16 rport; /* The remote port number in network byte order */
uint8 ttl; /* Default time-to-live */
/* Defines the UDP callback */
@ -237,63 +238,63 @@ struct uip_stats
{
struct
{
uip_stats_t drop; /* Number of dropped packets at the IP layer. */
uip_stats_t recv; /* Number of received packets at the IP layer. */
uip_stats_t sent; /* Number of sent packets at the IP layer. */
uip_stats_t drop; /* Number of dropped packets at the IP layer */
uip_stats_t recv; /* Number of received packets at the IP layer */
uip_stats_t sent; /* Number of sent packets at the IP layer */
uip_stats_t vhlerr; /* Number of packets dropped due to wrong
IP version or header length. */
IP version or header length */
uip_stats_t hblenerr; /* Number of packets dropped due to wrong
IP length, high byte. */
IP length, high byte */
uip_stats_t lblenerr; /* Number of packets dropped due to wrong
IP length, low byte. */
IP length, low byte */
uip_stats_t fragerr; /* Number of packets dropped since they
were IP fragments. */
were IP fragments */
uip_stats_t chkerr; /* Number of packets dropped due to IP
checksum errors. */
checksum errors */
uip_stats_t protoerr; /* Number of packets dropped since they
were neither ICMP, UDP nor TCP. */
} ip; /* IP statistics. */
were neither ICMP, UDP nor TCP */
} ip; /* IP statistics */
struct
{
uip_stats_t drop; /* Number of dropped ICMP packets. */
uip_stats_t recv; /* Number of received ICMP packets. */
uip_stats_t sent; /* Number of sent ICMP packets. */
uip_stats_t typeerr; /* Number of ICMP packets with a wrong type. */
} icmp; /* ICMP statistics. */
uip_stats_t drop; /* Number of dropped ICMP packets */
uip_stats_t recv; /* Number of received ICMP packets */
uip_stats_t sent; /* Number of sent ICMP packets */
uip_stats_t typeerr; /* Number of ICMP packets with a wrong type */
} icmp; /* ICMP statistics */
struct
{
uip_stats_t drop; /* Number of dropped TCP segments. */
uip_stats_t recv; /* Number of received TCP segments. */
uip_stats_t sent; /* Number of sent TCP segments. */
uip_stats_t chkerr; /* Number of TCP segments with a bad checksum. */
uip_stats_t ackerr; /* Number of TCP segments with a bad ACK number. */
uip_stats_t rst; /* Number of recevied TCP RST (reset) segments. */
uip_stats_t rexmit; /* Number of retransmitted TCP segments. */
uip_stats_t drop; /* Number of dropped TCP segments */
uip_stats_t recv; /* Number of received TCP segments */
uip_stats_t sent; /* Number of sent TCP segments */
uip_stats_t chkerr; /* Number of TCP segments with a bad checksum */
uip_stats_t ackerr; /* Number of TCP segments with a bad ACK number */
uip_stats_t rst; /* Number of recevied TCP RST (reset) segments */
uip_stats_t rexmit; /* Number of retransmitted TCP segments */
uip_stats_t syndrop; /* Number of dropped SYNs due to too few
available connections. */
uip_stats_t synrst; /* Number of SYNs for closed ports triggering a RST. */
} tcp; /* TCP statistics. */
available connections */
uip_stats_t synrst; /* Number of SYNs for closed ports triggering a RST */
} tcp; /* TCP statistics */
#ifdef CONFIG_NET_UDP
struct
{
uip_stats_t drop; /* Number of dropped UDP segments. */
uip_stats_t recv; /* Number of recived UDP segments. */
uip_stats_t sent; /* Number of sent UDP segments. */
uip_stats_t chkerr; /* Number of UDP segments with a bad checksum. */
} udp; /* UDP statistics. */
uip_stats_t drop; /* Number of dropped UDP segments */
uip_stats_t recv; /* Number of recived UDP segments */
uip_stats_t sent; /* Number of sent UDP segments */
uip_stats_t chkerr; /* Number of UDP segments with a bad checksum */
} udp; /* UDP statistics */
#endif /* CONFIG_NET_UDP */
};
/* The TCP and IP headers. */
/* The TCP and IP headers */
struct uip_tcpip_hdr
{
#ifdef CONFIG_NET_IPv6
/* IPv6 Ip header. */
/* IPv6 Ip header */
uint8 vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
uint8 tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
@ -306,7 +307,7 @@ struct uip_tcpip_hdr
#else /* CONFIG_NET_IPv6 */
/* IPv4 IP header. */
/* IPv4 IP header */
uint8 vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 tos; /* 8-bit Type of service (e.g., 6=TCP) */
@ -321,7 +322,7 @@ struct uip_tcpip_hdr
#endif /* CONFIG_NET_IPv6 */
/* TCP header. */
/* TCP header */
uint16 srcport;
uint16 destport;
@ -335,13 +336,13 @@ struct uip_tcpip_hdr
uint8 optdata[4];
};
/* The ICMP and IP headers. */
/* The ICMP and IP headers */
struct uip_icmpip_hdr
{
#ifdef CONFIG_NET_IPv6
/* IPv6 Ip header. */
/* IPv6 Ip header */
uint8 vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
uint8 tcf; /* Bits 0-3: traffic class (LS), bits 4-7: flow label (MS) */
@ -354,7 +355,7 @@ struct uip_icmpip_hdr
#else /* CONFIG_NET_IPv6 */
/* IPv4 IP header. */
/* IPv4 IP header */
uint8 vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 tos; /* 8-bit Type of service (e.g., 6=TCP) */
@ -369,7 +370,7 @@ struct uip_icmpip_hdr
#endif /* CONFIG_NET_IPv6 */
/* ICMP (echo) header. */
/* ICMP (echo) header */
uint8 type;
uint8 icode;
@ -392,13 +393,13 @@ struct uip_icmpip_hdr
#endif /* !CONFIG_NET_IPv6 */
};
/* The UDP and IP headers. */
/* The UDP and IP headers */
struct uip_udpip_hdr
{
#ifdef CONFIG_NET_IPv6
/* IPv6 Ip header. */
/* IPv6 Ip header */
uint8 vtc; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
uint8 tcf; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
@ -411,7 +412,7 @@ struct uip_udpip_hdr
#else /* CONFIG_NET_IPv6 */
/* IPv4 header. */
/* IPv4 header */
uint8 vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 tos; /* 8-bit Type of service (e.g., 6=TCP) */
@ -426,7 +427,7 @@ struct uip_udpip_hdr
#endif /* CONFIG_NET_IPv6 */
/* UDP header. */
/* UDP header */
uint16 srcport;
uint16 destport;
@ -434,7 +435,7 @@ struct uip_udpip_hdr
uint16 udpchksum;
};
/* Representation of a 48-bit Ethernet address. */
/* Representation of a 48-bit Ethernet address */
struct uip_eth_addr
{
@ -465,7 +466,7 @@ extern void *uip_urgdata;
extern uint16 uip_urglen; /* Length of (received) urgent data */
#endif /* UIP_URGDATA > 0 */
/* The current UDP connection. */
/* The current UDP connection */
#ifdef CONFIG_NET_UDP
extern struct uip_udp_conn *uip_udp_conn;
@ -570,7 +571,7 @@ int uip_listen(uint16 port);
int uip_unlisten(uint16 port);
/* Check if a connection has outstanding (i.e., unacknowledged) data. */
/* Check if a connection has outstanding (i.e., unacknowledged) data */
#define uip_outstanding(conn) ((conn)->len)

View File

@ -42,9 +42,12 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <arch/irq.h>
#include "net-internal.h"
@ -95,6 +98,7 @@ static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
{
struct accept_s *pstate = (struct accept_s *)listener->accept_private;
int ret = -EINVAL;
if (pstate)
{
/* Get the connection address */
@ -112,6 +116,7 @@ static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
listener->accept = NULL;
ret = OK;
}
return ret;
}
@ -265,12 +270,12 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
}
pnewsock = sockfd_socket(newfd);
if (newfd)
if (!pnewsock)
{
err = ENFILE;
goto errout_with_socket;
}
/* Set the socket state to accepting */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_ACCEPT);
@ -286,6 +291,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
state.acpt_addr = inaddr;
state.acpt_newconn = NULL;
state.acpt_result = OK;
sem_init(&state.acpt_sem, 0, 0);
/* Set up the callback in the connection */
@ -299,7 +305,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
* automatically re-enabled when the task restarts.
*/
ret = sem_wait(&state. acpt_sem);
ret = sem_wait(&state.acpt_sem);
/* Make sure that no further interrupts are processed */
@ -333,10 +339,11 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
goto errout_with_socket;
}
/* Initialize the socket structure */
/* Initialize the socket structure and mark the socket as connected */
pnewsock->s_type = SOCK_STREAM;
pnewsock->s_conn = state.acpt_newconn;
pnewsock->s_type = SOCK_STREAM;
pnewsock->s_conn = state.acpt_newconn;
pnewsock->s_flags |= _SF_CONNECTED;
return newfd;
errout_with_socket:

View File

@ -128,7 +128,7 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
break;
#endif
default:
err = -EBADF;
err = EBADF;
goto errout;
}

View File

@ -1,6 +1,5 @@
/****************************************************************************
* net/uip/uip-udppoll.c
* Poll for the availability of UDP TX data
* net/uip/uip-initialize.c
*
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>

View File

@ -45,6 +45,8 @@
#ifdef CONFIG_NET
#include <sys/types.h>
#include <debug.h>
#include <net/uip/uipopt.h>
#include "uip-internal.h"

View File

@ -115,6 +115,7 @@ uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 fla
dbg("No listener on connection\n");
#ifdef CONFIG_NET_STATISTICS
uip_stat.tcp.syndrop++;
uip_stat.tcp.drop++;
#endif

View File

@ -105,7 +105,12 @@ static uint8 g_tcp_sequence[4];
* selected.
*
* Return:
* 0 on success, -ERRNO on failure
* 0 on success, negated errno on failure:
*
* EADDRINUSE
* The given address is already in use.
* EADDRNOTAVAIL
* Cannot assign requested address (unlikely)
*
* Assumptions:
* Interrupts are disabled
@ -117,7 +122,9 @@ static int uip_selectport(uint16 portno)
if (portno == 0)
{
/* No local port assigned. Loop until we find a valid listen port number
* that is not being used by any other connection.
* that is not being used by any other connection. NOTE the following loop
* is assumed to terminate but could not if all 32000-4096+1 ports are
* in used (unlikely).
*/
do
@ -134,7 +141,7 @@ static int uip_selectport(uint16 portno)
g_last_tcp_port = 4096;
}
}
while (uip_tcplistener(g_last_tcp_port));
while (uip_tcplistener(htons(g_last_tcp_port)));
}
else
{
@ -150,7 +157,7 @@ static int uip_selectport(uint16 portno)
}
}
/* Return the selecte or verified port number */
/* Return the selected or verified port number */
return portno;
}
@ -372,8 +379,8 @@ struct uip_conn *uip_nexttcpconn(struct uip_conn *conn)
* Name: uip_tcplistener()
*
* Description:
* Given a local port number, find the TCP connection that listens on this
* this port.
* Given a local port number (in network byte order), find the TCP
* connection that listens on this this port.
*
* Primary uses: (1) to determine if a port number is available, (2) to
* To idenfity the socket that will accept new connections on a local port.
@ -390,7 +397,7 @@ struct uip_conn *uip_tcplistener(uint16 portno)
for (i = 0; i < UIP_CONNS; i++)
{
conn = &g_tcp_connections[i];
if (conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(g_last_tcp_port))
if (conn->tcpstateflags != UIP_CLOSED && conn->lport == portno)
{
/* The portnumber is in use, return the connection */
@ -420,27 +427,34 @@ struct uip_conn *uip_tcpaccept(struct uip_tcpip_hdr *buf)
{
/* Fill in the necessary fields for the new connection. */
conn->rto = conn->timer = UIP_RTO;
conn->sa = 0;
conn->sv = 4;
conn->nrtx = 0;
conn->lport = buf->destport;
conn->rport = buf->srcport;
uip_ipaddr_copy(conn->ripaddr, buf->srcipaddr);
conn->rto = UIP_RTO;
conn->timer = UIP_RTO;
conn->sa = 0;
conn->sv = 4;
conn->nrtx = 0;
conn->lport = buf->destport;
conn->rport = buf->srcport;
uip_ipaddr_copy(conn->ripaddr, uip_ip4addr_conv(buf->srcipaddr));
conn->tcpstateflags = UIP_SYN_RCVD;
conn->snd_nxt[0] = g_tcp_sequence[0];
conn->snd_nxt[1] = g_tcp_sequence[1];
conn->snd_nxt[2] = g_tcp_sequence[2];
conn->snd_nxt[3] = g_tcp_sequence[3];
conn->len = 1;
conn->snd_nxt[0] = g_tcp_sequence[0];
conn->snd_nxt[1] = g_tcp_sequence[1];
conn->snd_nxt[2] = g_tcp_sequence[2];
conn->snd_nxt[3] = g_tcp_sequence[3];
conn->len = 1;
/* rcv_nxt should be the seqno from the incoming packet + 1. */
conn->rcv_nxt[3] = buf->seqno[3];
conn->rcv_nxt[2] = buf->seqno[2];
conn->rcv_nxt[1] = buf->seqno[1];
conn->rcv_nxt[0] = buf->seqno[0];
conn->rcv_nxt[3] = buf->seqno[3];
conn->rcv_nxt[2] = buf->seqno[2];
conn->rcv_nxt[1] = buf->seqno[1];
conn->rcv_nxt[0] = buf->seqno[0];
/* And, finally, put the connection structure into the active list.
* Interrupts should already be disabled in this context.
*/
dq_addlast(&conn->node, &g_active_tcp_connections);
}
return conn;
}
@ -479,6 +493,9 @@ void uip_tcpnextsequence(void)
* This function implements the UIP specific parts of the standard TCP
* bind() operation.
*
* Return:
* 0 on success or -EADDRINUSE on failure
*
* Assumptions:
* This function is called from normal user level code.
*
@ -496,7 +513,7 @@ int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in *addr)
/* Verify or select a local port */
flags = irqsave();
port = uip_selectport(ntohs(conn->lport));
port = uip_selectport(ntohs(addr->sin_port));
irqrestore(flags);
if (port < 0)
@ -504,8 +521,19 @@ int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in *addr)
return port;
}
#warning "Need to implement bind logic"
return -ENOSYS;
/* Save the local address in the connection structure. Note that the requested
* local IP address is saved but not used. At present, only a single network
* interface is supported, the IP address is not of importance.
*/
conn->lport = addr->sin_port;
#ifdef CONFIG_NET_IPv6
uip_ipaddr_copy(conn->lipaddr, addr->sin6_addr.in6_u.u6_addr16);
#else
uip_ipaddr_copy(conn->lipaddr, addr->sin_addr.s_addr);
#endif
return OK;
}
/****************************************************************************