diff options
Diffstat (limited to 'nuttx/net/uip/uip.c')
-rw-r--r-- | nuttx/net/uip/uip.c | 565 |
1 files changed, 228 insertions, 337 deletions
diff --git a/nuttx/net/uip/uip.c b/nuttx/net/uip/uip.c index 7fa2e3b7e..830f34551 100644 --- a/nuttx/net/uip/uip.c +++ b/nuttx/net/uip/uip.c @@ -93,6 +93,8 @@ extern void uip_log(char *msg); # define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */ +#include "uip-internal.h" + /**************************************************************************** * Definitions ****************************************************************************/ @@ -175,11 +177,9 @@ uint16 uip_flags; /* The uip_flags variable is used for communica * program. */ struct uip_conn *uip_conn; /* uip_conn always points to the current connection. */ -struct uip_conn uip_conns[UIP_CONNS]; - /* The uip_conns array holds all TCP connections. */ uint16 uip_listenports[UIP_LISTENPORTS]; /* The uip_listenports list all currently listning ports. */ - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP struct uip_udp_conn *uip_udp_conn; struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; #endif /* CONFIG_NET_UDP */ @@ -222,11 +222,10 @@ struct uip_eth_addr uip_ethaddr = {{ 0,0,0,0,0,0 }}; static uint16 ipid; /* Ths ipid variable is an increasing number that is * used for the IP ID field. */ -static uint8 iss[4]; /* The iss variable is used for the TCP initial - * sequence number. */ - -static uint16 lastport; /* Keeps track of the last port used for a new +#ifdef CONFIG_NET_UDP +static uint16 g_last_udp_port; /* Keeps track of the last port used for a new * connection. */ +#endif /* Temporary variables. */ static uint8 c, opt; @@ -236,38 +235,6 @@ static uint16 tmp16; * Private Functions ****************************************************************************/ -#if !UIP_ARCH_ADD32 -static void uip_add32(uint8 *op32, uint16 op16) -{ - uip_acc32[3] = op32[3] + (op16 & 0xff); - uip_acc32[2] = op32[2] + (op16 >> 8); - uip_acc32[1] = op32[1]; - uip_acc32[0] = op32[0]; - - if (uip_acc32[2] < (op16 >> 8)) - { - ++uip_acc32[1]; - if (uip_acc32[1] == 0) - { - ++uip_acc32[0]; - } - } - - if (uip_acc32[3] < (op16 & 0xff)) - { - ++uip_acc32[2]; - if (uip_acc32[2] == 0) - { - ++uip_acc32[1]; - if (uip_acc32[1] == 0) - { - ++uip_acc32[0]; - } - } - } -} -#endif /* UIP_ARCH_ADD32 */ - #if !UIP_ARCH_CHKSUM static uint16 chksum(uint16 sum, const uint8 *data, uint16 len) { @@ -340,34 +307,7 @@ static uint16 uip_icmp6chksum(void) #endif /* UIP_ARCH_CHKSUM */ -/* Given a port number, find the socket bound to the port number. - * Primary use: to determine if a port number is available. - */ - -struct uip_conn *uip_find_conn( uint16 portno ) -{ - struct uip_conn *conn; - int i; - - /* Check if this port number is already in use, and if so try to find - * another one. - */ - - for (i = 0; i < UIP_CONNS; i++) - { - conn = &uip_conns[i]; - if (conn->tcpstateflags != UIP_CLOSED && conn->lport == htons(lastport)) - { - /* The portnumber is in use */ - - return conn; - } - } - - return NULL; -} - - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP struct uip_udp_conn *uip_find_udp_conn( uint16 portno ) { struct uip_udp_conn *conn; @@ -375,7 +315,7 @@ struct uip_udp_conn *uip_find_udp_conn( uint16 portno ) for (i = 0; i < UIP_UDP_CONNS; i++) { - if (uip_udp_conns[i].lport == htons(lastport)) + if (uip_udp_conns[i].lport == htons(g_last_udp_port)) { return conn; } @@ -398,6 +338,38 @@ void uip_setipid(uint16 id) /* Calculate the Internet checksum over a buffer. */ +#if !UIP_ARCH_ADD32 +void uip_add32(uint8 *op32, uint16 op16) +{ + uip_acc32[3] = op32[3] + (op16 & 0xff); + uip_acc32[2] = op32[2] + (op16 >> 8); + uip_acc32[1] = op32[1]; + uip_acc32[0] = op32[0]; + + if (uip_acc32[2] < (op16 >> 8)) + { + ++uip_acc32[1]; + if (uip_acc32[1] == 0) + { + ++uip_acc32[0]; + } + } + + if (uip_acc32[3] < (op16 & 0xff)) + { + ++uip_acc32[2]; + if (uip_acc32[2] == 0) + { + ++uip_acc32[1]; + if (uip_acc32[1] == 0) + { + ++uip_acc32[0]; + } + } + } +} +#endif /* UIP_ARCH_ADD32 */ + #if !UIP_ARCH_CHKSUM uint16 uip_chksum(uint16 *data, uint16 len) { @@ -426,7 +398,7 @@ uint16 uip_tcpchksum(void) /* Calculate the UDP checksum of the packet in uip_buf and uip_appdata. */ - #ifdef CONFIG_NET_UDP_CHECKSUMS +#ifdef CONFIG_NET_UDP_CHECKSUMS uint16 uip_udpchksum(void) { return upper_layer_chksum(UIP_PROTO_UDP); @@ -441,17 +413,19 @@ void uip_init(void) uip_listenports[c] = 0; } - for (c = 0; c < UIP_CONNS; ++c) - { - uip_conns[c].tcpstateflags = UIP_CLOSED; - } - lastport = 1024; + /* Initialize the TCP/IP connection structures */ + + uip_tcpinit(); + + /* Initialize the UDP connection structures */ - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP for (c = 0; c < UIP_UDP_CONNS; ++c) { uip_udp_conns[c].lport = 0; } + + g_last_udp_port = 1024; #endif /* CONFIG_NET_UDP */ /* IPv4 initialization. */ @@ -460,83 +434,6 @@ void uip_init(void) #endif /* UIP_FIXEDADDR */ } -struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, uint16 rport) -{ - struct uip_conn *conn, *cconn; - int i; - - /* Find an unused local port number. Loop until we find a valid listen port - * number that is not being used by any other connection. - */ - - do - { - /* Guess that the next available port number will be the one after - * the last port number assigned. - */ - - ++lastport; - - /* Make sure that the port number is within range */ - if (lastport >= 32000) - { - lastport = 4096; - } - } - while (uip_find_conn(lastport)); - - /* Now find an available connection structure */ - - conn = 0; - for (i = 0; i < UIP_CONNS; i++) - { - cconn = &uip_conns[i]; - if (cconn->tcpstateflags == UIP_CLOSED) - { - conn = cconn; - break; - } - - if (cconn->tcpstateflags == UIP_TIME_WAIT) - { - if (conn == 0 || cconn->timer > conn->timer) - { - conn = cconn; - } - } - } - - /* Return an error if no connection is available */ - - if (conn == 0) - { - return 0; - } - - /* Initialize and return the connection structure, bind it to the port number */ - - conn->tcpstateflags = UIP_SYN_SENT; - - conn->snd_nxt[0] = iss[0]; - conn->snd_nxt[1] = iss[1]; - conn->snd_nxt[2] = iss[2]; - conn->snd_nxt[3] = iss[3]; - - conn->initialmss = conn->mss = UIP_TCP_MSS; - - conn->len = 1; /* TCP length of the SYN is one. */ - conn->nrtx = 0; - conn->timer = 1; /* Send the SYN next time around. */ - conn->rto = UIP_RTO; - conn->sa = 0; - conn->sv = 16; /* Initial value of the RTT variance. */ - conn->lport = htons(lastport); - conn->rport = rport; - uip_ipaddr_copy(&conn->ripaddr, ripaddr); - - return conn; -} - #ifdef CONFIG_NET_UDP struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport) { @@ -553,15 +450,15 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport) * the last port number assigned. */ - ++lastport; + ++g_last_udp_port; /* Make sure that the port number is within range */ - if (lastport >= 32000) + if (g_last_udp_port >= 32000) { - lastport = 4096; + g_last_udp_port = 4096; } } - while (uip_find_udp_conn(lastport)); + while (uip_find_udp_conn(g_last_udp_port)); /* Now find an available UDP connection structure */ @@ -584,7 +481,7 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport) /* Initialize and return the connection structure, bind it to the port number */ - conn->lport = HTONS(lastport); + conn->lport = HTONS(g_last_udp_port); conn->rport = rport; if (ripaddr == NULL) @@ -616,15 +513,17 @@ void uip_unlisten(uint16 port) void uip_listen(uint16 port) { - for (c = 0; c < UIP_LISTENPORTS; ++c) { - if (uip_listenports[c] == 0) { - uip_listenports[c] = port; - return; + for (c = 0; c < UIP_LISTENPORTS; ++c) + { + if (uip_listenports[c] == 0) + { + uip_listenports[c] = port; + return; + } } - } } -/* XXX: IP fragment reassembly: not well-tested. */ +/* IP fragment reassembly: not well-tested. */ #if UIP_REASSEMBLY && !defined(CONFIG_NET_IPv6) #define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) @@ -644,113 +543,133 @@ static uint8 uip_reass(void) uint16 i; /* If ip_reasstmr is zero, no packet is present in the buffer, so we - write the IP header of the fragment into the reassembly - buffer. The timer is updated with the maximum age. */ - if (uip_reasstmr == 0) { - memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); - uip_reasstmr = UIP_REASS_MAXAGE; - uip_reassflags = 0; - /* Clear the bitmap. */ - memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); - } + * write the IP header of the fragment into the reassembly + * buffer. The timer is updated with the maximum age. + */ - /* Check if the incoming fragment matches the one currently present - in the reasembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if (BUF->srcipaddr[0] == FBUF->srcipaddr[0] && - BUF->srcipaddr[1] == FBUF->srcipaddr[1] && - BUF->destipaddr[0] == FBUF->destipaddr[0] && - BUF->destipaddr[1] == FBUF->destipaddr[1] && - BUF->ipid[0] == FBUF->ipid[0] && - BUF->ipid[1] == FBUF->ipid[1]) { - - len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; - offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; - - /* If the offset or the offset + fragment length overflows the - reassembly buffer, we discard the entire packet. */ - if (offset > UIP_REASS_BUFSIZE || - offset + len > UIP_REASS_BUFSIZE) { - uip_reasstmr = 0; - goto nullreturn; + if (uip_reasstmr == 0) + { + memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); + uip_reasstmr = UIP_REASS_MAXAGE; + uip_reassflags = 0; + + /* Clear the bitmap. */ + memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); } - /* Copy the fragment into the reassembly buffer, at the right - offset. */ - memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], - (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), - len); + /* Check if the incoming fragment matches the one currently present + * in the reasembly buffer. If so, we proceed with copying the + * fragment into the buffer. + */ + + if (BUF->srcipaddr[0] == FBUF->srcipaddr[0] && BUF->srcipaddr[1] == FBUF->srcipaddr[1] && + BUF->destipaddr[0] == FBUF->destipaddr[0] && BUF->destipaddr[1] == FBUF->destipaddr[1] && + BUF->ipid[0] == FBUF->ipid[0] && BUF->ipid[1] == FBUF->ipid[1]) + { + len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; + offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; + + /* If the offset or the offset + fragment length overflows the + * reassembly buffer, we discard the entire packet. + */ + + if (offset > UIP_REASS_BUFSIZE || offset + len > UIP_REASS_BUFSIZE) + { + uip_reasstmr = 0; + goto nullreturn; + } + + /* Copy the fragment into the reassembly buffer, at the right offset. */ + + memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), len); /* Update the bitmap. */ - if (offset / (8 * 8) == (offset + len) / (8 * 8)) { - /* If the two endpoints are in the same byte, we only update - that byte. */ - - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7] & - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } else { - /* If the two endpoints are in different bytes, we update the - bytes in the endpoints and fill the stuff inbetween with - 0xff. */ - uip_reassbitmap[offset / (8 * 8)] |= - bitmap_bits[(offset / 8 ) & 7]; - for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { - uip_reassbitmap[i] = 0xff; - } - uip_reassbitmap[(offset + len) / (8 * 8)] |= - ~bitmap_bits[((offset + len) / 8 ) & 7]; - } - /* If this fragment has the More Fragments flag set to zero, we - know that this is the last fragment, so we can calculate the - size of the entire packet. We also set the - IP_REASS_FLAG_LASTFRAG flag to indicate that we have received - the final fragment. */ + if (offset / (8 * 8) == (offset + len) / (8 * 8)) + { + /* If the two endpoints are in the same byte, we only update that byte. */ + + uip_reassbitmap[offset / (8 * 8)] |= + bitmap_bits[(offset / 8 ) & 7] & ~bitmap_bits[((offset + len) / 8 ) & 7]; - if ((BUF->ipoffset[0] & IP_MF) == 0) { - uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; - uip_reasslen = offset + len; - } + } + else + { + /* If the two endpoints are in different bytes, we update the bytes + * in the endpoints and fill the stuff inbetween with 0xff. + */ - /* Finally, we check if we have a full packet in the buffer. We do - this by checking if we have the last fragment and if all bits - in the bitmap are set. */ - if (uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { - /* Check all bytes up to and including all but the last byte in - the bitmap. */ - for (i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { - if (uip_reassbitmap[i] != 0xff) { - goto nullreturn; - } + uip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8 ) & 7]; + for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) + { + uip_reassbitmap[i] = 0xff; + } + uip_reassbitmap[(offset + len) / (8 * 8)] |= ~bitmap_bits[((offset + len) / 8 ) & 7]; } - /* Check the last byte in the bitmap. It should contain just the - right amount of bits. */ - if (uip_reassbitmap[uip_reasslen / (8 * 8)] != - (uint8)~bitmap_bits[uip_reasslen / 8 & 7]) { - goto nullreturn; + /* If this fragment has the More Fragments flag set to zero, we know that + * this is the last fragment, so we can calculate the size of the entire + * packet. We also set the IP_REASS_FLAG_LASTFRAG flag to indicate that + * we have received the final fragment. + */ + + if ((BUF->ipoffset[0] & IP_MF) == 0) + { + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; + uip_reasslen = offset + len; } - /* If we have come this far, we have a full packet in the - buffer, so we allocate a pbuf and copy the packet into it. We - also reset the timer. */ - uip_reasstmr = 0; - memcpy(BUF, FBUF, uip_reasslen); - - /* Pretend to be a "normal" (i.e., not fragmented) IP packet - from now on. */ - BUF->ipoffset[0] = BUF->ipoffset[1] = 0; - BUF->len[0] = uip_reasslen >> 8; - BUF->len[1] = uip_reasslen & 0xff; - BUF->ipchksum = 0; - BUF->ipchksum = ~(uip_ipchksum()); - - return uip_reasslen; - } + /* Finally, we check if we have a full packet in the buffer. We do this + * by checking if we have the last fragment and if all bits in the bitmap + * are set. + */ + + if (uip_reassflags & UIP_REASS_FLAG_LASTFRAG) + { + /* Check all bytes up to and including all but the last byte in + * the bitmap. + */ + + for (i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) + { + if (uip_reassbitmap[i] != 0xff) + { + goto nullreturn; + } + } + + /* Check the last byte in the bitmap. It should contain just the + * right amount of bits. + */ + + if (uip_reassbitmap[uip_reasslen / (8 * 8)] != (uint8)~bitmap_bits[uip_reasslen / 8 & 7]) + { + goto nullreturn; + } + + /* If we have come this far, we have a full packet in the buffer, + * so we allocate a pbuf and copy the packet into it. We also reset + * the timer. + */ + + uip_reasstmr = 0; + memcpy(BUF, FBUF, uip_reasslen); + + /* Pretend to be a "normal" (i.e., not fragmented) IP packet from + * now on. + */ + + BUF->ipoffset[0] = BUF->ipoffset[1] = 0; + BUF->len[0] = uip_reasslen >> 8; + BUF->len[1] = uip_reasslen & 0xff; + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); + + return uip_reasslen; + } } - nullreturn: +nullreturn: return 0; } #endif /* UIP_REASSEMBLY */ @@ -768,7 +687,7 @@ void uip_interrupt(uint8 flag) { register struct uip_conn *uip_connr = uip_conn; - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP if (flag == UIP_UDP_SEND_CONN) { goto udp_send; @@ -805,22 +724,13 @@ void uip_interrupt(uint8 flag) } #endif /* UIP_REASSEMBLY */ - /* Increase the initial sequence number */ + /* Increase the TCP sequence number */ - if (++iss[3] == 0) - { - if (++iss[2] == 0) - { - if (++iss[1] == 0) - { - ++iss[0]; - } - } - } + uip_tcpnextsequence(); /* Reset the length variables. */ - uip_len = 0; + uip_len = 0; uip_slen = 0; /* Check if the connection is in a state in which we simply wait @@ -935,7 +845,7 @@ void uip_interrupt(uint8 flag) goto drop; } - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP if (flag == UIP_UDP_TIMER) { if (uip_udp_conn->lport != 0) @@ -1105,7 +1015,7 @@ void uip_interrupt(uint8 flag) goto tcp_input; } - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP if (BUF->proto == UIP_PROTO_UDP) { goto udp_input; @@ -1247,14 +1157,14 @@ void uip_interrupt(uint8 flag) #endif /* !CONFIG_NET_IPv6 */ - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP /* UDP input processing. */ udp_input: /* UDP processing is really just a hack. We don't do anything to the UDP/IP headers, but let the UDP application do all the hard work. If the application sets uip_slen, it has a packet to send. */ - #ifdef CONFIG_NET_UDP_CHECKSUMS +#ifdef CONFIG_NET_UDP_CHECKSUMS uip_len = uip_len - UIP_IPUDPH_LEN; uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; if (UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) @@ -1269,9 +1179,8 @@ void uip_interrupt(uint8 flag) #endif /* UIP_UDP_CHECKSUMS */ /* Demultiplex this UDP packet between the UDP "connections". */ - for (uip_udp_conn = &uip_udp_conns[0]; - uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; - ++uip_udp_conn) + + for (uip_udp_conn = &uip_udp_conns[0]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; uip_udp_conn++) { /* If the local UDP port is non-zero, the connection is considered * to be used. If so, the local port number is checked against the @@ -1282,13 +1191,12 @@ void uip_interrupt(uint8 flag) * address of the packet is checked. */ - if (uip_udp_conn->lport != 0 && - UDPBUF->destport == uip_udp_conn->lport && + if (uip_udp_conn->lport != 0 && UDPBUF->destport == uip_udp_conn->lport && (uip_udp_conn->rport == 0 || - UDPBUF->srcport == uip_udp_conn->rport) && - (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || - uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || - uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) + UDPBUF->srcport == uip_udp_conn->rport) && + (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || + uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || + uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { goto udp_found; } @@ -1336,7 +1244,7 @@ void uip_interrupt(uint8 flag) uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; - #ifdef CONFIG_NET_UDP_CHECKSUMS +#ifdef CONFIG_NET_UDP_CHECKSUMS /* Calculate UDP checksum. */ UDPBUF->udpchksum = ~(uip_udpchksum()); if (UDPBUF->udpchksum == 0) @@ -1357,30 +1265,27 @@ void uip_interrupt(uint8 flag) if (uip_tcpchksum() != 0xffff) { /* Compute and check the TCP checksum. */ + UIP_STAT(++uip_stat.tcp.drop); UIP_STAT(++uip_stat.tcp.chkerr); UIP_LOG("tcp: bad checksum."); goto drop; } - /* Demultiplex this segment. */ - /* First check any active connections. */ - for (uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; - ++uip_connr) + /* Demultiplex this segment. First check any active connections. */ + + uip_connr = uip_tcpactive(BUF); + if (uip_connr) { - if (uip_connr->tcpstateflags != UIP_CLOSED && - BUF->destport == uip_connr->lport && - BUF->srcport == uip_connr->rport && - uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) - { - goto found; - } + goto found; } /* If we didn't find and active connection that expected the packet, - either this packet is an old duplicate, or this is a SYN packet - destined for a connection in LISTEN. If the SYN flag isn't set, - it is an old packet and we send a RST. */ + * either this packet is an old duplicate, or this is a SYN packet + * destined for a connection in LISTEN. If the SYN flag isn't set, + * it is an old packet and we send a RST. + */ + if ((BUF->flags & TCP_CTL) != TCP_SYN) { goto reset; @@ -1455,57 +1360,43 @@ void uip_interrupt(uint8 flag) goto tcp_send_noconn; /* This label will be jumped to if we matched the incoming packet - with a connection in LISTEN. In that case, we should create a new - connection and send a SYNACK in return. */ - found_listen: - /* First we check if there are any connections avaliable. Unused - connections are kept in the same table as used connections, but - unused ones have the tcpstate set to CLOSED. Also, connections in - TIME_WAIT are kept track of and we'll use the oldest one if no - CLOSED connections are found. Thanks to Eddie C. Dost for a very - nice algorithm for the TIME_WAIT search. */ - uip_connr = 0; - for (c = 0; c < UIP_CONNS; ++c) - { - if (uip_conns[c].tcpstateflags == UIP_CLOSED) - { - uip_connr = &uip_conns[c]; - break; - } - if (uip_conns[c].tcpstateflags == UIP_TIME_WAIT) - { - if (uip_connr == 0 || uip_conns[c].timer > uip_connr->timer) - { - uip_connr = &uip_conns[c]; - } - } - } + * with a connection in LISTEN. In that case, we should create a new + * connection and send a SYNACK in return. + */ - if (uip_connr == 0) +found_listen: + + /* First allocate a new connection structure */ + + uip_connr = uip_tcpalloc(); + if (!uip_connr) { /* All connections are used already, we drop packet and hope that - the remote end will retransmit the packet at a time when we - have more spare connections. */ + * the remote end will retransmit the packet at a time when we + * have more spare connections. + */ + UIP_STAT(++uip_stat.tcp.syndrop); - UIP_LOG("tcp: found no unused connections."); - goto drop; - } + UIP_LOG("tcp: found no unused connections."); + goto drop; + } uip_conn = uip_connr; /* Fill in the necessary fields for the new connection. */ - uip_connr->rto = uip_connr->timer = UIP_RTO; - uip_connr->sa = 0; - uip_connr->sv = 4; - uip_connr->nrtx = 0; + + uip_connr->rto = uip_connr->timer = UIP_RTO; + uip_connr->sa = 0; + uip_connr->sv = 4; + uip_connr->nrtx = 0; uip_connr->lport = BUF->destport; uip_connr->rport = BUF->srcport; uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); uip_connr->tcpstateflags = UIP_SYN_RCVD; - uip_connr->snd_nxt[0] = iss[0]; - uip_connr->snd_nxt[1] = iss[1]; - uip_connr->snd_nxt[2] = iss[2]; - uip_connr->snd_nxt[3] = iss[3]; + uip_connr->snd_nxt[0] = g_tcp_sequence[0]; + uip_connr->snd_nxt[1] = g_tcp_sequence[1]; + uip_connr->snd_nxt[2] = g_tcp_sequence[2]; + uip_connr->snd_nxt[3] = g_tcp_sequence[3]; uip_connr->len = 1; /* rcv_nxt should be the seqno from the incoming packet + 1. */ @@ -2119,7 +2010,7 @@ void uip_interrupt(uint8 flag) BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); - #ifdef CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP ip_send_nolen: #endif /* CONFIG_NET_UDP */ |