mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-09-24 01:33:50 +08:00
Replaced all tabs with two spaces (regardless of indentation is correct).
This commit is contained in:
@@ -452,7 +452,7 @@ static void dhcp_handle_ack(struct netif *netif)
|
||||
/* boot file name */
|
||||
if (dhcp->msg_in->file[0]) {
|
||||
dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1);
|
||||
strcpy(dhcp->boot_file_name, dhcp->msg_in->file);
|
||||
strcpy(dhcp->boot_file_name, dhcp->msg_in->file);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ lwip_chksum(void *dataptr, int len)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
u16_t
|
||||
inet_chksum_pseudo(struct pbuf *p,
|
||||
struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t proto, u16_t proto_len)
|
||||
struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t proto, u16_t proto_len)
|
||||
{
|
||||
u32_t acc;
|
||||
struct pbuf *q;
|
||||
@@ -291,30 +291,30 @@ inet_chksum_pbuf(struct pbuf *p)
|
||||
*/
|
||||
u8_t *inet_ntoa(u32_t addr)
|
||||
{
|
||||
static u8_t str[16];
|
||||
u8_t inv[3];
|
||||
u8_t *rp;
|
||||
u8_t *ap;
|
||||
u8_t rem;
|
||||
u8_t n;
|
||||
u8_t i;
|
||||
static u8_t str[16];
|
||||
u8_t inv[3];
|
||||
u8_t *rp;
|
||||
u8_t *ap;
|
||||
u8_t rem;
|
||||
u8_t n;
|
||||
u8_t i;
|
||||
|
||||
rp = str;
|
||||
ap = (u8_t *)&addr;
|
||||
for(n = 0; n < 4; n++) {
|
||||
i = 0;
|
||||
do {
|
||||
rem = *ap % (u8_t)10;
|
||||
*ap /= (u8_t)10;
|
||||
inv[i++] = '0' + rem;
|
||||
} while(*ap);
|
||||
while(i--)
|
||||
*rp++ = inv[i];
|
||||
*rp++ = '.';
|
||||
ap++;
|
||||
}
|
||||
*--rp = 0;
|
||||
return str;
|
||||
rp = str;
|
||||
ap = (u8_t *)&addr;
|
||||
for(n = 0; n < 4; n++) {
|
||||
i = 0;
|
||||
do {
|
||||
rem = *ap % (u8_t)10;
|
||||
*ap /= (u8_t)10;
|
||||
inv[i++] = '0' + rem;
|
||||
} while(*ap);
|
||||
while(i--)
|
||||
*rp++ = inv[i];
|
||||
*rp++ = '.';
|
||||
ap++;
|
||||
}
|
||||
*--rp = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -82,8 +82,8 @@ chksum(void *dataptr, u16_t len)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
u16_t
|
||||
inet_chksum_pseudo(struct pbuf *p,
|
||||
struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t proto, u32_t proto_len)
|
||||
struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t proto, u32_t proto_len)
|
||||
{
|
||||
u32_t acc;
|
||||
struct pbuf *q;
|
||||
|
||||
@@ -127,7 +127,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
pbuf_header(p, hlen);
|
||||
ip_output_if (p, &(iphdr->src), IP_HDRINCL,
|
||||
IPH_TTL(iphdr), IP_PROTO_ICMP, inp);
|
||||
IPH_TTL(iphdr), IP_PROTO_ICMP, inp);
|
||||
break;
|
||||
default:
|
||||
DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d code %d not supported.\n", (int)type, (int)code));
|
||||
@@ -169,7 +169,7 @@ icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
|
||||
snmp_inc_icmpoutdestunreachs();
|
||||
|
||||
ip_output(q, NULL, &(iphdr->src),
|
||||
ICMP_TTL, IP_PROTO_ICMP);
|
||||
ICMP_TTL, IP_PROTO_ICMP);
|
||||
pbuf_free(q);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@@ -210,7 +210,7 @@ icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
|
||||
/* increase number of destination unreachable messages attempted to send */
|
||||
snmp_inc_icmpouttimeexcds();
|
||||
ip_output(q, NULL, &(iphdr->src),
|
||||
ICMP_TTL, IP_PROTO_ICMP);
|
||||
ICMP_TTL, IP_PROTO_ICMP);
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
*/
|
||||
static struct pbuf *
|
||||
copy_from_pbuf(struct pbuf *p, u16_t * offset,
|
||||
u8_t * buffer, u16_t len)
|
||||
u8_t * buffer, u16_t len)
|
||||
{
|
||||
u16_t l;
|
||||
|
||||
@@ -98,7 +98,7 @@ ip_reass_timer(void *arg)
|
||||
ip_reasstmr--;
|
||||
sys_timeout(IP_REASS_TMO, ip_reass_timer, NULL);
|
||||
} else if (ip_reasstmr == 1)
|
||||
ip_reasstmr = 0;
|
||||
ip_reasstmr = 0;
|
||||
}
|
||||
|
||||
struct pbuf *
|
||||
@@ -147,8 +147,8 @@ ip_reass(struct pbuf *p)
|
||||
reassembly buffer, we discard the entire packet. */
|
||||
if (offset > IP_REASS_BUFSIZE || offset + len > IP_REASS_BUFSIZE) {
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,
|
||||
offset + len, IP_REASS_BUFSIZE));
|
||||
("ip_reass: fragment outside of buffer (%d:%d/%d).\n", offset,
|
||||
offset + len, IP_REASS_BUFSIZE));
|
||||
sys_untimeout(ip_reass_timer, NULL);
|
||||
ip_reasstmr = 0;
|
||||
goto nullreturn;
|
||||
@@ -157,33 +157,33 @@ ip_reass(struct pbuf *p)
|
||||
/* Copy the fragment into the reassembly buffer, at the right
|
||||
offset. */
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: copying with offset %d into %d:%d\n", offset,
|
||||
IP_HLEN + offset, IP_HLEN + offset + len));
|
||||
("ip_reass: copying with offset %d into %d:%d\n", offset,
|
||||
IP_HLEN + offset, IP_HLEN + offset + len));
|
||||
i = IPH_HL(fraghdr) * 4;
|
||||
copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len);
|
||||
|
||||
/* Update the bitmap. */
|
||||
if (offset / (8 * 8) == (offset + len) / (8 * 8)) {
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: updating single byte in bitmap.\n"));
|
||||
("ip_reass: updating single byte in bitmap.\n"));
|
||||
/* If the two endpoints are in the same byte, we only update
|
||||
that byte. */
|
||||
ip_reassbitmap[offset / (8 * 8)] |=
|
||||
bitmap_bits[(offset / 8) & 7] &
|
||||
~bitmap_bits[((offset + len) / 8) & 7];
|
||||
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. */
|
||||
ip_reassbitmap[offset / (8 * 8)] |= bitmap_bits[(offset / 8) & 7];
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: updating many bytes in bitmap (%d:%d).\n",
|
||||
1 + offset / (8 * 8), (offset + len) / (8 * 8)));
|
||||
("ip_reass: updating many bytes in bitmap (%d:%d).\n",
|
||||
1 + offset / (8 * 8), (offset + len) / (8 * 8)));
|
||||
for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
|
||||
ip_reassbitmap[i] = 0xff;
|
||||
ip_reassbitmap[i] = 0xff;
|
||||
}
|
||||
ip_reassbitmap[(offset + len) / (8 * 8)] |=
|
||||
~bitmap_bits[((offset + len) / 8) & 7];
|
||||
~bitmap_bits[((offset + len) / 8) & 7];
|
||||
}
|
||||
|
||||
/* If this fragment has the More Fragments flag set to zero, we
|
||||
@@ -196,8 +196,8 @@ ip_reass(struct pbuf *p)
|
||||
ip_reassflags |= IP_REASS_FLAG_LASTFRAG;
|
||||
ip_reasslen = offset + len;
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: last fragment seen, total len %d\n",
|
||||
ip_reasslen));
|
||||
("ip_reass: last fragment seen, total len %d\n",
|
||||
ip_reasslen));
|
||||
}
|
||||
|
||||
/* Finally, we check if we have a full packet in the buffer. We do
|
||||
@@ -207,22 +207,22 @@ ip_reass(struct pbuf *p)
|
||||
/* Check all bytes up to and including all but the last byte in
|
||||
the bitmap. */
|
||||
for (i = 0; i < ip_reasslen / (8 * 8) - 1; ++i) {
|
||||
if (ip_reassbitmap[i] != 0xff) {
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n",
|
||||
i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
|
||||
goto nullreturn;
|
||||
}
|
||||
if (ip_reassbitmap[i] != 0xff) {
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: last fragment seen, bitmap %d/%d failed (%x)\n",
|
||||
i, ip_reasslen / (8 * 8) - 1, ip_reassbitmap[i]));
|
||||
goto nullreturn;
|
||||
}
|
||||
}
|
||||
/* Check the last byte in the bitmap. It should contain just the
|
||||
right amount of bits. */
|
||||
if (ip_reassbitmap[ip_reasslen / (8 * 8)] !=
|
||||
(u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",
|
||||
ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
|
||||
ip_reassbitmap[ip_reasslen / (8 * 8)]));
|
||||
goto nullreturn;
|
||||
(u8_t) ~ bitmap_bits[ip_reasslen / 8 & 7]) {
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: last fragment seen, bitmap %d didn't contain %x (%x)\n",
|
||||
ip_reasslen / (8 * 8), ~bitmap_bits[ip_reasslen / 8 & 7],
|
||||
ip_reassbitmap[ip_reasslen / (8 * 8)]));
|
||||
goto nullreturn;
|
||||
}
|
||||
|
||||
/* Pretend to be a "normal" (i.e., not fragmented) IP packet
|
||||
@@ -242,25 +242,25 @@ ip_reass(struct pbuf *p)
|
||||
pbuf_free(p);
|
||||
p = pbuf_alloc(PBUF_LINK, ip_reasslen, PBUF_POOL);
|
||||
if (p != NULL) {
|
||||
i = 0;
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
/* Copy enough bytes to fill this pbuf in the chain. The
|
||||
available data in the pbuf is given by the q->len
|
||||
variable. */
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: memcpy from %p (%d) to %p, %d bytes\n",
|
||||
&ip_reassbuf[i], i, q->payload,
|
||||
q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
|
||||
memcpy(q->payload, &ip_reassbuf[i],
|
||||
q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
|
||||
i += q->len;
|
||||
}
|
||||
i = 0;
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
/* Copy enough bytes to fill this pbuf in the chain. The
|
||||
available data in the pbuf is given by the q->len
|
||||
variable. */
|
||||
DEBUGF(IP_REASS_DEBUG,
|
||||
("ip_reass: memcpy from %p (%d) to %p, %d bytes\n",
|
||||
&ip_reassbuf[i], i, q->payload,
|
||||
q->len > ip_reasslen - i ? ip_reasslen - i : q->len));
|
||||
memcpy(q->payload, &ip_reassbuf[i],
|
||||
q->len > ip_reasslen - i ? ip_reasslen - i : q->len);
|
||||
i += q->len;
|
||||
}
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip_frag.fw;
|
||||
++lwip_stats.ip_frag.fw;
|
||||
#endif /* IP_STATS */
|
||||
} else {
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip_frag.memerr;
|
||||
++lwip_stats.ip_frag.memerr;
|
||||
#endif /* IP_STATS */
|
||||
}
|
||||
DEBUGF(IP_REASS_DEBUG, ("ip_reass: p %p\n", (void*)p));
|
||||
|
||||
@@ -101,7 +101,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
/* DEBUGF("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len);*/
|
||||
ip_output_if (p, &(iphdr->src), IP_HDRINCL,
|
||||
iphdr->hoplim, IP_PROTO_ICMP, inp);
|
||||
iphdr->hoplim, IP_PROTO_ICMP, inp);
|
||||
break;
|
||||
default:
|
||||
DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d not supported.\n", (int)type));
|
||||
@@ -140,7 +140,7 @@ icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
|
||||
#endif /* ICMP_STATS */
|
||||
|
||||
ip_output(q, NULL,
|
||||
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
|
||||
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
|
||||
pbuf_free(q);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@@ -171,7 +171,7 @@ icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
|
||||
++lwip_stats.icmp.xmit;
|
||||
#endif /* ICMP_STATS */
|
||||
ip_output(q, NULL,
|
||||
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
|
||||
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
||||
pbuf_free(p);
|
||||
DEBUGF(IP_DEBUG, ("Unsupported transport protocol %u\n",
|
||||
iphdr->nexthdr));
|
||||
iphdr->nexthdr));
|
||||
|
||||
#ifdef IP_STATS
|
||||
++lwip_stats.ip.proterr;
|
||||
@@ -259,8 +259,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t ttl,
|
||||
u8_t proto, struct netif *netif)
|
||||
u8_t ttl,
|
||||
u8_t proto, struct netif *netif)
|
||||
{
|
||||
struct ip_hdr *iphdr;
|
||||
|
||||
@@ -320,7 +320,7 @@ ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
u8_t ttl, u8_t proto)
|
||||
u8_t ttl, u8_t proto)
|
||||
{
|
||||
struct netif *netif;
|
||||
if ((netif = ip_route(dest)) == NULL) {
|
||||
@@ -346,40 +346,40 @@ ip_debug_print(struct pbuf *p)
|
||||
DEBUGF(IP_DEBUG, ("IP header:\n"));
|
||||
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(IP_DEBUG, ("|%2d | %x%x | %x%x | (v, traffic class, flow label)\n",
|
||||
iphdr->v,
|
||||
iphdr->tclass1, iphdr->tclass2,
|
||||
iphdr->flow1, iphdr->flow2));
|
||||
iphdr->v,
|
||||
iphdr->tclass1, iphdr->tclass2,
|
||||
iphdr->flow1, iphdr->flow2));
|
||||
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(IP_DEBUG, ("| %5u | %2u | %2u | (len, nexthdr, hoplim)\n",
|
||||
ntohs(iphdr->len),
|
||||
iphdr->nexthdr,
|
||||
iphdr->hoplim));
|
||||
ntohs(iphdr->len),
|
||||
iphdr->nexthdr,
|
||||
iphdr->hoplim));
|
||||
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
|
||||
ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[0]) & 0xffff));
|
||||
ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[0]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
|
||||
ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[1]) & 0xffff));
|
||||
ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[1]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
|
||||
ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[2]) & 0xffff));
|
||||
ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[2]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
|
||||
ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[3]) & 0xffff));
|
||||
ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->src.addr[3]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
|
||||
ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[0]) & 0xffff));
|
||||
ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[0]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
|
||||
ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[1]) & 0xffff));
|
||||
ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[1]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
|
||||
ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[2]) & 0xffff));
|
||||
ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[2]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
|
||||
ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[3]) & 0xffff));
|
||||
ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
|
||||
ntohl(iphdr->dest.addr[3]) & 0xffff));
|
||||
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||
}
|
||||
#endif /* IP_DEBUG */
|
||||
|
||||
@@ -202,7 +202,7 @@ mem_realloc(void *rmem, mem_size_t newsize)
|
||||
sys_sem_wait(mem_sem);
|
||||
|
||||
LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
|
||||
(u8_t *)rmem < (u8_t *)ram_end);
|
||||
(u8_t *)rmem < (u8_t *)ram_end);
|
||||
|
||||
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
|
||||
DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));
|
||||
@@ -275,24 +275,24 @@ mem_malloc(mem_size_t size)
|
||||
lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
|
||||
/* if (lwip_stats.mem.max < lwip_stats.mem.used) {
|
||||
lwip_stats.mem.max = lwip_stats.mem.used;
|
||||
} */
|
||||
} */
|
||||
if (lwip_stats.mem.max < ptr2) {
|
||||
lwip_stats.mem.max = ptr2;
|
||||
}
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
if (mem == lfree) {
|
||||
/* Find next free block after mem */
|
||||
/* Find next free block after mem */
|
||||
while (lfree->used && lfree != ram_end) {
|
||||
lfree = (struct mem *)&ram[lfree->next];
|
||||
lfree = (struct mem *)&ram[lfree->next];
|
||||
}
|
||||
LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);
|
||||
}
|
||||
sys_sem_signal(mem_sem);
|
||||
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
|
||||
(u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);
|
||||
(u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);
|
||||
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
|
||||
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
|
||||
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
|
||||
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,35 +79,35 @@ static const u16_t memp_num[MEMP_MAX] = {
|
||||
};
|
||||
|
||||
static u8_t memp_memory[(MEMP_NUM_PBUF *
|
||||
MEM_ALIGN_SIZE(sizeof(struct pbuf) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_UDP_PCB *
|
||||
MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCP_PCB *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCP_PCB_LISTEN *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCP_SEG *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_NETBUF *
|
||||
MEM_ALIGN_SIZE(sizeof(struct netbuf) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_NETCONN *
|
||||
MEM_ALIGN_SIZE(sizeof(struct netconn) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_API_MSG *
|
||||
MEM_ALIGN_SIZE(sizeof(struct api_msg) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCPIP_MSG *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_SYS_TIMEOUT *
|
||||
MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
|
||||
sizeof(struct memp)))];
|
||||
MEM_ALIGN_SIZE(sizeof(struct pbuf) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_UDP_PCB *
|
||||
MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCP_PCB *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCP_PCB_LISTEN *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCP_SEG *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_NETBUF *
|
||||
MEM_ALIGN_SIZE(sizeof(struct netbuf) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_NETCONN *
|
||||
MEM_ALIGN_SIZE(sizeof(struct netconn) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_API_MSG *
|
||||
MEM_ALIGN_SIZE(sizeof(struct api_msg) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_TCPIP_MSG *
|
||||
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
|
||||
sizeof(struct memp)) +
|
||||
MEMP_NUM_SYS_TIMEOUT *
|
||||
MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
|
||||
sizeof(struct memp)))];
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#if !SYS_LIGHTWEIGHT_PROT
|
||||
@@ -125,10 +125,10 @@ memp_sanity(void)
|
||||
for(m = memp_tab[i]; m != NULL; m = m->next) {
|
||||
c = 1;
|
||||
for(n = memp_tab[i]; n != NULL; n = n->next) {
|
||||
if (n == m) {
|
||||
--c;
|
||||
if (n == m) {
|
||||
--c;
|
||||
}
|
||||
if (c < 0) return 0; /* LW was: abort(); */
|
||||
if (c < 0) return 0; /* LW was: abort(); */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,9 +159,9 @@ memp_init(void)
|
||||
m = memp;
|
||||
|
||||
for(j = 0; j < memp_num[i]; ++j) {
|
||||
m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
|
||||
memp = m;
|
||||
m = m->next;
|
||||
m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
|
||||
memp = m;
|
||||
m = m->next;
|
||||
}
|
||||
memp->next = NULL;
|
||||
memp = m;
|
||||
@@ -197,11 +197,11 @@ memp_malloc(memp_t type)
|
||||
}
|
||||
#endif /* MEMP_STATS */
|
||||
LWIP_ASSERT("memp_malloc: memp properly aligned",
|
||||
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
||||
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
||||
|
||||
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
|
||||
/* initialize memp memory with zeroes */
|
||||
memset(mem, 0, memp_sizes[type]);
|
||||
memset(mem, 0, memp_sizes[type]);
|
||||
return mem;
|
||||
} else {
|
||||
DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
|
||||
|
||||
@@ -112,7 +112,7 @@ netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
|
||||
|
||||
void
|
||||
netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
|
||||
struct ip_addr *gw)
|
||||
struct ip_addr *gw)
|
||||
{
|
||||
netif_set_ipaddr(netif, ipaddr);
|
||||
netif_set_netmask(netif, netmask);
|
||||
@@ -131,13 +131,13 @@ void netif_remove(struct netif * netif)
|
||||
/* look for netif further down the list */
|
||||
struct netif * tmpNetif;
|
||||
for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {
|
||||
if (tmpNetif->next == netif) {
|
||||
tmpNetif->next = netif->next;
|
||||
if (tmpNetif->next == netif) {
|
||||
tmpNetif->next = netif->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmpNetif == NULL)
|
||||
return; /* we didn't find any netif today */
|
||||
}
|
||||
if (tmpNetif == NULL)
|
||||
return; /* we didn't find any netif today */
|
||||
}
|
||||
/* this netif is default? */
|
||||
if (netif_default == netif)
|
||||
@@ -211,7 +211,7 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
|
||||
#endif
|
||||
ip_addr_set(&(netif->ip_addr), ipaddr);
|
||||
DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%u\n",
|
||||
netif->name[0], netif->name[1],
|
||||
netif->name[0], netif->name[1],
|
||||
(u8_t)(ntohl(netif->ip_addr.addr) >> 24 & 0xff),
|
||||
(u8_t)(ntohl(netif->ip_addr.addr) >> 16 & 0xff),
|
||||
(u8_t)(ntohl(netif->ip_addr.addr) >> 8 & 0xff),
|
||||
@@ -223,11 +223,11 @@ netif_set_gw(struct netif *netif, struct ip_addr *gw)
|
||||
{
|
||||
ip_addr_set(&(netif->gw), gw);
|
||||
DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %u.%u.%u.%u\n",
|
||||
netif->name[0], netif->name[1],
|
||||
(u8_t)(ntohl(netif->gw.addr) >> 24 & 0xff),
|
||||
(u8_t)(ntohl(netif->gw.addr) >> 16 & 0xff),
|
||||
(u8_t)(ntohl(netif->gw.addr) >> 8 & 0xff),
|
||||
(u8_t)(ntohl(netif->gw.addr) & 0xff)));
|
||||
netif->name[0], netif->name[1],
|
||||
(u8_t)(ntohl(netif->gw.addr) >> 24 & 0xff),
|
||||
(u8_t)(ntohl(netif->gw.addr) >> 16 & 0xff),
|
||||
(u8_t)(ntohl(netif->gw.addr) >> 8 & 0xff),
|
||||
(u8_t)(ntohl(netif->gw.addr) & 0xff)));
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
@@ -235,11 +235,11 @@ netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
|
||||
{
|
||||
ip_addr_set(&(netif->netmask), netmask);
|
||||
DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %u.%u.%u.%u\n",
|
||||
netif->name[0], netif->name[1],
|
||||
(u8_t)(ntohl(netif->netmask.addr) >> 24 & 0xff),
|
||||
(u8_t)(ntohl(netif->netmask.addr) >> 16 & 0xff),
|
||||
(u8_t)(ntohl(netif->netmask.addr) >> 8 & 0xff),
|
||||
(u8_t)(ntohl(netif->netmask.addr) & 0xff)));
|
||||
netif->name[0], netif->name[1],
|
||||
(u8_t)(ntohl(netif->netmask.addr) >> 24 & 0xff),
|
||||
(u8_t)(ntohl(netif->netmask.addr) >> 16 & 0xff),
|
||||
(u8_t)(ntohl(netif->netmask.addr) >> 8 & 0xff),
|
||||
(u8_t)(ntohl(netif->netmask.addr) & 0xff)));
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
@@ -247,7 +247,7 @@ netif_set_default(struct netif *netif)
|
||||
{
|
||||
netif_default = netif;
|
||||
DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
|
||||
netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
|
||||
netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
|
||||
@@ -69,8 +69,8 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
|
||||
|
||||
if (time == SYS_ARCH_TIMEOUT) {
|
||||
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
|
||||
could be fetched. We should now call the timeout handler and
|
||||
deallocate the memory allocated for the timeout. */
|
||||
could be fetched. We should now call the timeout handler and
|
||||
deallocate the memory allocated for the timeout. */
|
||||
tmptimeout = timeouts->next;
|
||||
timeouts->next = tmptimeout->next;
|
||||
h = tmptimeout->h;
|
||||
@@ -78,19 +78,19 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
|
||||
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
|
||||
if (h != NULL) {
|
||||
DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
|
||||
h(arg);
|
||||
h(arg);
|
||||
}
|
||||
|
||||
/* We try again to fetch a message from the mbox. */
|
||||
goto again;
|
||||
} else {
|
||||
/* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
|
||||
occured. The time variable is set to the number of
|
||||
milliseconds we waited for the message. */
|
||||
occured. The time variable is set to the number of
|
||||
milliseconds we waited for the message. */
|
||||
if (time <= timeouts->next->time) {
|
||||
timeouts->next->time -= time;
|
||||
timeouts->next->time -= time;
|
||||
} else {
|
||||
timeouts->next->time = 0;
|
||||
timeouts->next->time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,29 +124,29 @@ sys_sem_wait(sys_sem_t sem)
|
||||
|
||||
if (time == SYS_ARCH_TIMEOUT) {
|
||||
/* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
|
||||
could be fetched. We should now call the timeout handler and
|
||||
deallocate the memory allocated for the timeout. */
|
||||
could be fetched. We should now call the timeout handler and
|
||||
deallocate the memory allocated for the timeout. */
|
||||
tmptimeout = timeouts->next;
|
||||
timeouts->next = tmptimeout->next;
|
||||
h = tmptimeout->h;
|
||||
arg = tmptimeout->arg;
|
||||
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
|
||||
if (h != NULL) {
|
||||
DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));
|
||||
h(arg);
|
||||
DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void *)h, (void *)arg));
|
||||
h(arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* We try again to fetch a message from the mbox. */
|
||||
goto again;
|
||||
} else {
|
||||
/* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
|
||||
occured. The time variable is set to the number of
|
||||
milliseconds we waited for the message. */
|
||||
occured. The time variable is set to the number of
|
||||
milliseconds we waited for the message. */
|
||||
if (time <= timeouts->next->time) {
|
||||
timeouts->next->time -= time;
|
||||
timeouts->next->time -= time;
|
||||
} else {
|
||||
timeouts->next->time = 0;
|
||||
timeouts->next->time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,13 +186,13 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
||||
for(t = timeouts->next; t != NULL; t = t->next) {
|
||||
timeout->time -= t->time;
|
||||
if (t->next == NULL ||
|
||||
t->next->time > timeout->time) {
|
||||
if (t->next != NULL) {
|
||||
t->next->time -= timeout->time;
|
||||
}
|
||||
timeout->next = t->next;
|
||||
t->next = timeout;
|
||||
break;
|
||||
t->next->time > timeout->time) {
|
||||
if (t->next != NULL) {
|
||||
t->next->time -= timeout->time;
|
||||
}
|
||||
timeout->next = t->next;
|
||||
t->next = timeout;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,11 +282,11 @@ sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
|
||||
void
|
||||
sys_msleep(u32_t ms)
|
||||
{
|
||||
sys_sem_t delaysem = sys_sem_new(0);
|
||||
sys_sem_t delaysem = sys_sem_new(0);
|
||||
|
||||
sys_sem_wait_timeout(delaysem, ms);
|
||||
sys_sem_wait_timeout(delaysem, ms);
|
||||
|
||||
sys_sem_free(delaysem);
|
||||
sys_sem_free(delaysem);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ const u8_t tcp_backoff[13] =
|
||||
/* The TCP PCB lists. */
|
||||
struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
|
||||
struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
|
||||
state in which they accept or send
|
||||
data. */
|
||||
state in which they accept or send
|
||||
data. */
|
||||
struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
|
||||
|
||||
struct tcp_pcb *tcp_tmp_pcb;
|
||||
@@ -274,9 +274,9 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
cpcb != NULL; cpcb = cpcb->next) {
|
||||
if (cpcb->local_port == port) {
|
||||
if (ip_addr_isany(&(cpcb->local_ip)) ||
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
|
||||
return ERR_USE;
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
|
||||
return ERR_USE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,7 +352,7 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
||||
tcp_ack(pcb);
|
||||
}
|
||||
DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %u bytes, wnd %u (%u).\n",
|
||||
len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
|
||||
len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
@@ -405,7 +405,7 @@ tcp_new_port(void)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
|
||||
err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
|
||||
err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
|
||||
{
|
||||
u32_t optdata;
|
||||
err_t ret;
|
||||
@@ -439,9 +439,9 @@ tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
|
||||
|
||||
/* Build an MSS option */
|
||||
optdata = htonl(((u32_t)2 << 24) |
|
||||
((u32_t)4 << 16) |
|
||||
(((u32_t)pcb->mss / 256) << 8) |
|
||||
(pcb->mss & 255));
|
||||
((u32_t)4 << 16) |
|
||||
(((u32_t)pcb->mss / 256) << 8) |
|
||||
(pcb->mss & 255));
|
||||
|
||||
ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);
|
||||
if (ret == ERR_OK) {
|
||||
@@ -539,7 +539,7 @@ tcp_slowtmr(void)
|
||||
/* Check if this PCB has stayed too long in SYN-RCVD */
|
||||
if (pcb->state == SYN_RCVD) {
|
||||
if ((u32_t)(tcp_ticks - pcb->tmr) >
|
||||
TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
|
||||
TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
|
||||
++pcb_remove;
|
||||
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
|
||||
}
|
||||
@@ -551,7 +551,7 @@ tcp_slowtmr(void)
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_active_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
|
||||
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
|
||||
prev->next = pcb->next;
|
||||
} else {
|
||||
/* This PCB was the first. */
|
||||
@@ -569,12 +569,12 @@ tcp_slowtmr(void)
|
||||
/* We check if we should poll the connection. */
|
||||
++pcb->polltmr;
|
||||
if (pcb->polltmr >= pcb->pollinterval) {
|
||||
pcb->polltmr = 0;
|
||||
pcb->polltmr = 0;
|
||||
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
|
||||
TCP_EVENT_POLL(pcb, err);
|
||||
if (err == ERR_OK) {
|
||||
tcp_output(pcb);
|
||||
}
|
||||
TCP_EVENT_POLL(pcb, err);
|
||||
if (err == ERR_OK) {
|
||||
tcp_output(pcb);
|
||||
}
|
||||
}
|
||||
|
||||
prev = pcb;
|
||||
@@ -602,7 +602,7 @@ tcp_slowtmr(void)
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_tw_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
|
||||
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
|
||||
prev->next = pcb->next;
|
||||
} else {
|
||||
/* This PCB was the first. */
|
||||
@@ -761,7 +761,7 @@ tcp_kill_prio(u8_t prio)
|
||||
}
|
||||
if (inactive != NULL) {
|
||||
DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n",
|
||||
(void *)inactive, inactivity));
|
||||
(void *)inactive, inactivity));
|
||||
tcp_abort(inactive);
|
||||
}
|
||||
}
|
||||
@@ -783,7 +783,7 @@ tcp_kill_timewait(void)
|
||||
}
|
||||
if (inactive != NULL) {
|
||||
DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n",
|
||||
(void *)inactive, inactivity));
|
||||
(void *)inactive, inactivity));
|
||||
tcp_abort(inactive);
|
||||
}
|
||||
}
|
||||
@@ -875,7 +875,7 @@ tcp_arg(struct tcp_pcb *pcb, void *arg)
|
||||
#if LWIP_CALLBACK_API
|
||||
void
|
||||
tcp_recv(struct tcp_pcb *pcb,
|
||||
err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
|
||||
err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
|
||||
{
|
||||
pcb->recv = recv;
|
||||
}
|
||||
@@ -892,7 +892,7 @@ tcp_recv(struct tcp_pcb *pcb,
|
||||
#if LWIP_CALLBACK_API
|
||||
void
|
||||
tcp_sent(struct tcp_pcb *pcb,
|
||||
err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
|
||||
err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
|
||||
{
|
||||
pcb->sent = sent;
|
||||
}
|
||||
@@ -909,7 +909,7 @@ tcp_sent(struct tcp_pcb *pcb,
|
||||
#if LWIP_CALLBACK_API
|
||||
void
|
||||
tcp_err(struct tcp_pcb *pcb,
|
||||
void (* errf)(void *arg, err_t err))
|
||||
void (* errf)(void *arg, err_t err))
|
||||
{
|
||||
pcb->errf = errf;
|
||||
}
|
||||
@@ -926,7 +926,7 @@ tcp_err(struct tcp_pcb *pcb,
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
tcp_poll(struct tcp_pcb *pcb,
|
||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
|
||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
|
||||
{
|
||||
#if LWIP_CALLBACK_API
|
||||
pcb->poll = poll;
|
||||
@@ -945,7 +945,7 @@ tcp_poll(struct tcp_pcb *pcb,
|
||||
#if LWIP_CALLBACK_API
|
||||
void
|
||||
tcp_accept(struct tcp_pcb *pcb,
|
||||
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
|
||||
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
|
||||
{
|
||||
((struct tcp_pcb_listen *)pcb)->accept = accept;
|
||||
}
|
||||
@@ -1042,28 +1042,28 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
|
||||
DEBUGF(TCP_DEBUG, ("TCP header:\n"));
|
||||
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(TCP_DEBUG, ("| %04x | %04x | (src port, dest port)\n",
|
||||
tcphdr->src, tcphdr->dest));
|
||||
tcphdr->src, tcphdr->dest));
|
||||
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(TCP_DEBUG, ("| %08lu | (seq no)\n",
|
||||
tcphdr->seqno));
|
||||
tcphdr->seqno));
|
||||
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(TCP_DEBUG, ("| %08lu | (ack no)\n",
|
||||
tcphdr->ackno));
|
||||
tcphdr->ackno));
|
||||
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(TCP_DEBUG, ("| %2u | |%u%u%u%u%u| %5u | (offset, flags (",
|
||||
TCPH_OFFSET(tcphdr),
|
||||
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 3 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 2 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 1 & 1,
|
||||
TCPH_FLAGS(tcphdr) & 1,
|
||||
tcphdr->wnd));
|
||||
TCPH_OFFSET(tcphdr),
|
||||
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 3 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 2 & 1,
|
||||
TCPH_FLAGS(tcphdr) >> 1 & 1,
|
||||
TCPH_FLAGS(tcphdr) & 1,
|
||||
tcphdr->wnd));
|
||||
tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
|
||||
DEBUGF(TCP_DEBUG, ("), win)\n"));
|
||||
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(TCP_DEBUG, ("| 0x%04x | %5u | (chksum, urgp)\n",
|
||||
ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
|
||||
ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
|
||||
DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -134,11 +134,11 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
/* Verify TCP checksum. */
|
||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_TCP, p->tot_len) != 0) {
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_TCP, p->tot_len) != 0) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n", inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_TCP, p->tot_len)));
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_TCP, p->tot_len)));
|
||||
#if TCP_DEBUG
|
||||
tcp_debug_print(tcphdr);
|
||||
#endif /* TCP_DEBUG */
|
||||
@@ -180,13 +180,13 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
|
||||
|
||||
/* Move this PCB to the front of the list so that subsequent
|
||||
lookups will be faster (we exploit locality in TCP segment
|
||||
arrivals). */
|
||||
lookups will be faster (we exploit locality in TCP segment
|
||||
arrivals). */
|
||||
LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
|
||||
if (prev != NULL) {
|
||||
prev->next = pcb->next;
|
||||
pcb->next = tcp_active_pcbs;
|
||||
tcp_active_pcbs = pcb;
|
||||
prev->next = pcb->next;
|
||||
pcb->next = tcp_active_pcbs;
|
||||
tcp_active_pcbs = pcb;
|
||||
}
|
||||
LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
|
||||
break;
|
||||
@@ -201,16 +201,16 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
|
||||
if (pcb->remote_port == tcphdr->src &&
|
||||
pcb->local_port == tcphdr->dest &&
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
|
||||
pcb->local_port == tcphdr->dest &&
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
|
||||
/* We don't really care enough to move this PCB to the front
|
||||
of the list since we are not very likely to receive that
|
||||
many segments for connections in TIME-WAIT. */
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
|
||||
tcp_timewait_input(pcb);
|
||||
pbuf_free(p);
|
||||
return;
|
||||
/* We don't really care enough to move this PCB to the front
|
||||
of the list since we are not very likely to receive that
|
||||
many segments for connections in TIME-WAIT. */
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
|
||||
tcp_timewait_input(pcb);
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,23 +219,23 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
prev = NULL;
|
||||
for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||
if ((ip_addr_isany(&(lpcb->local_ip)) ||
|
||||
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
|
||||
lpcb->local_port == tcphdr->dest) {
|
||||
/* Move this PCB to the front of the list so that subsequent
|
||||
lookups will be faster (we exploit locality in TCP segment
|
||||
arrivals). */
|
||||
if (prev != NULL) {
|
||||
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
|
||||
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
|
||||
lpcb->local_port == tcphdr->dest) {
|
||||
/* Move this PCB to the front of the list so that subsequent
|
||||
lookups will be faster (we exploit locality in TCP segment
|
||||
arrivals). */
|
||||
if (prev != NULL) {
|
||||
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
|
||||
/* our successor is the remainder of the listening list */
|
||||
lpcb->next = tcp_listen_pcbs;
|
||||
lpcb->next = tcp_listen_pcbs;
|
||||
/* put this listening pcb at the head of the listening list */
|
||||
tcp_listen_pcbs = lpcb;
|
||||
}
|
||||
tcp_listen_pcbs = lpcb;
|
||||
}
|
||||
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
||||
tcp_listen_input(lpcb);
|
||||
pbuf_free(p);
|
||||
return;
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
||||
tcp_listen_input(lpcb);
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
prev = (struct tcp_pcb *)lpcb;
|
||||
}
|
||||
@@ -273,41 +273,41 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
and that the pcb has been freed. If so, we don't do anything. */
|
||||
if (err != ERR_ABRT) {
|
||||
if (recv_flags & TF_RESET) {
|
||||
/* TF_RESET means that the connection was reset by the other
|
||||
end. We then call the error callback to inform the
|
||||
application that the connection is dead before we
|
||||
deallocate the PCB. */
|
||||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
/* TF_RESET means that the connection was reset by the other
|
||||
end. We then call the error callback to inform the
|
||||
application that the connection is dead before we
|
||||
deallocate the PCB. */
|
||||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
} else if (recv_flags & TF_CLOSED) {
|
||||
/* The connection has been closed and we will deallocate the
|
||||
PCB. */
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
/* The connection has been closed and we will deallocate the
|
||||
PCB. */
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
} else {
|
||||
err = ERR_OK;
|
||||
/* If the application has registered a "sent" function to be
|
||||
called when new send buffer space is available, we call it
|
||||
now. */
|
||||
if (pcb->acked > 0) {
|
||||
TCP_EVENT_SENT(pcb, pcb->acked, err);
|
||||
}
|
||||
err = ERR_OK;
|
||||
/* If the application has registered a "sent" function to be
|
||||
called when new send buffer space is available, we call it
|
||||
now. */
|
||||
if (pcb->acked > 0) {
|
||||
TCP_EVENT_SENT(pcb, pcb->acked, err);
|
||||
}
|
||||
|
||||
if (recv_data != NULL) {
|
||||
/* Notify application that data has been received. */
|
||||
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
|
||||
}
|
||||
|
||||
/* If a FIN segment was received, we call the callback
|
||||
function with a NULL buffer to indicate EOF. */
|
||||
if (recv_flags & TF_GOT_FIN) {
|
||||
TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
|
||||
}
|
||||
/* If there were no errors, we try to send something out. */
|
||||
if (err == ERR_OK) {
|
||||
tcp_output(pcb);
|
||||
}
|
||||
if (recv_data != NULL) {
|
||||
/* Notify application that data has been received. */
|
||||
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
|
||||
}
|
||||
|
||||
/* If a FIN segment was received, we call the callback
|
||||
function with a NULL buffer to indicate EOF. */
|
||||
if (recv_flags & TF_GOT_FIN) {
|
||||
TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
|
||||
}
|
||||
/* If there were no errors, we try to send something out. */
|
||||
if (err == ERR_OK) {
|
||||
tcp_output(pcb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,8 +334,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
++lwip_stats.tcp.drop;
|
||||
#endif /* TCP_STATS */
|
||||
tcp_rst(ackno, seqno + tcplen,
|
||||
&(iphdr->dest), &(iphdr->src),
|
||||
tcphdr->dest, tcphdr->src);
|
||||
&(iphdr->dest), &(iphdr->src),
|
||||
tcphdr->dest, tcphdr->src);
|
||||
}
|
||||
pbuf_free(p);
|
||||
}
|
||||
@@ -363,8 +363,8 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
RST. */
|
||||
DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
|
||||
tcp_rst(ackno + 1, seqno + tcplen,
|
||||
&(iphdr->dest), &(iphdr->src),
|
||||
tcphdr->dest, tcphdr->src);
|
||||
&(iphdr->dest), &(iphdr->src),
|
||||
tcphdr->dest, tcphdr->src);
|
||||
} else if (flags & TCP_SYN) {
|
||||
DEBUGF(DEMO_DEBUG, ("TCP connection request %d -> %d.\n", tcphdr->src, tcphdr->dest));
|
||||
npcb = tcp_alloc(pcb->prio);
|
||||
@@ -402,9 +402,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
|
||||
/* Build an MSS option. */
|
||||
optdata = htonl(((u32_t)2 << 24) |
|
||||
((u32_t)4 << 16) |
|
||||
(((u32_t)npcb->mss / 256) << 8) |
|
||||
(npcb->mss & 255));
|
||||
((u32_t)4 << 16) |
|
||||
(((u32_t)npcb->mss / 256) << 8) |
|
||||
(npcb->mss & 255));
|
||||
/* Send a SYN|ACK together with the MSS option. */
|
||||
tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);
|
||||
return tcp_output(npcb);
|
||||
@@ -453,12 +453,12 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
/* First, determine if the reset is acceptable. */
|
||||
if (pcb->state == SYN_SENT) {
|
||||
if (ackno == pcb->snd_nxt) {
|
||||
acceptable = 1;
|
||||
acceptable = 1;
|
||||
}
|
||||
} else {
|
||||
if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
|
||||
TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
||||
acceptable = 1;
|
||||
TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
||||
acceptable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,9 +470,9 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
return ERR_RST;
|
||||
} else {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
|
||||
seqno, pcb->rcv_nxt));
|
||||
seqno, pcb->rcv_nxt));
|
||||
DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
|
||||
seqno, pcb->rcv_nxt));
|
||||
seqno, pcb->rcv_nxt));
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
@@ -484,7 +484,7 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
switch (pcb->state) {
|
||||
case SYN_SENT:
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
|
||||
pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
if (flags & (TCP_ACK | TCP_SYN) &&
|
||||
ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
|
||||
pcb->rcv_nxt = seqno + 1;
|
||||
@@ -502,7 +502,7 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
tcp_parseopt(pcb);
|
||||
|
||||
/* Call the user specified function to call when sucessfully
|
||||
connected. */
|
||||
connected. */
|
||||
TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
|
||||
tcp_ack(pcb);
|
||||
}
|
||||
@@ -511,29 +511,29 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
if (flags & TCP_ACK &&
|
||||
!(flags & TCP_RST)) {
|
||||
if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
||||
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
|
||||
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
|
||||
pcb->state = ESTABLISHED;
|
||||
DEBUGF(DEMO_DEBUG, ("TCP connection established %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
|
||||
/* Call the accept function. */
|
||||
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
|
||||
if (err != ERR_OK) {
|
||||
/* If the accept function returns with an error, we abort
|
||||
the connection. */
|
||||
tcp_abort(pcb);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
/* If there was any data contained within this ACK,
|
||||
we'd better pass it on to the application as well. */
|
||||
tcp_receive(pcb);
|
||||
pcb->cwnd = pcb->mss;
|
||||
}
|
||||
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
|
||||
/* Call the accept function. */
|
||||
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
|
||||
if (err != ERR_OK) {
|
||||
/* If the accept function returns with an error, we abort
|
||||
the connection. */
|
||||
tcp_abort(pcb);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
/* If there was any data contained within this ACK,
|
||||
we'd better pass it on to the application as well. */
|
||||
tcp_receive(pcb);
|
||||
pcb->cwnd = pcb->mss;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CLOSE_WAIT:
|
||||
/* FALLTHROUGH */
|
||||
case ESTABLISHED:
|
||||
tcp_receive(pcb);
|
||||
tcp_receive(pcb);
|
||||
if (flags & TCP_FIN) {
|
||||
tcp_ack_now(pcb);
|
||||
pcb->state = CLOSE_WAIT;
|
||||
@@ -544,15 +544,15 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
if (flags & TCP_FIN) {
|
||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
||||
DEBUGF(DEMO_DEBUG,
|
||||
("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
tcp_ack_now(pcb);
|
||||
tcp_pcb_purge(pcb);
|
||||
TCP_RMV(&tcp_active_pcbs, pcb);
|
||||
pcb->state = TIME_WAIT;
|
||||
TCP_REG(&tcp_tw_pcbs, pcb);
|
||||
("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
tcp_ack_now(pcb);
|
||||
tcp_pcb_purge(pcb);
|
||||
TCP_RMV(&tcp_active_pcbs, pcb);
|
||||
pcb->state = TIME_WAIT;
|
||||
TCP_REG(&tcp_tw_pcbs, pcb);
|
||||
} else {
|
||||
tcp_ack_now(pcb);
|
||||
pcb->state = CLOSING;
|
||||
tcp_ack_now(pcb);
|
||||
pcb->state = CLOSING;
|
||||
}
|
||||
} else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
||||
pcb->state = FIN_WAIT_2;
|
||||
@@ -645,32 +645,32 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
pcb->acked = 0;
|
||||
|
||||
if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
|
||||
++pcb->dupacks;
|
||||
if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
|
||||
if (!(pcb->flags & TF_INFR)) {
|
||||
/* This is fast retransmit. Retransmit the first unacked segment. */
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",
|
||||
pcb->dupacks, pcb->lastack,
|
||||
ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
tcp_rexmit(pcb);
|
||||
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
|
||||
pcb->ssthresh = LWIP_MAX((pcb->snd_max -
|
||||
pcb->lastack) / 2,
|
||||
2 * pcb->mss);
|
||||
|
||||
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
|
||||
pcb->flags |= TF_INFR;
|
||||
} else {
|
||||
/* Inflate the congestion window, but not if it means that
|
||||
the value overflows. */
|
||||
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
|
||||
pcb->cwnd += pcb->mss;
|
||||
}
|
||||
}
|
||||
}
|
||||
++pcb->dupacks;
|
||||
if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
|
||||
if (!(pcb->flags & TF_INFR)) {
|
||||
/* This is fast retransmit. Retransmit the first unacked segment. */
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",
|
||||
pcb->dupacks, pcb->lastack,
|
||||
ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
tcp_rexmit(pcb);
|
||||
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
|
||||
pcb->ssthresh = LWIP_MAX((pcb->snd_max -
|
||||
pcb->lastack) / 2,
|
||||
2 * pcb->mss);
|
||||
|
||||
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
|
||||
pcb->flags |= TF_INFR;
|
||||
} else {
|
||||
/* Inflate the congestion window, but not if it means that
|
||||
the value overflows. */
|
||||
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
|
||||
pcb->cwnd += pcb->mss;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
|
||||
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
|
||||
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
||||
}
|
||||
} else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
||||
@@ -680,8 +680,8 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
in fast retransmit. Also reset the congestion window to the
|
||||
slow start threshold. */
|
||||
if (pcb->flags & TF_INFR) {
|
||||
pcb->flags &= ~TF_INFR;
|
||||
pcb->cwnd = pcb->ssthresh;
|
||||
pcb->flags &= ~TF_INFR;
|
||||
pcb->cwnd = pcb->ssthresh;
|
||||
}
|
||||
|
||||
/* Reset the number of retransmissions. */
|
||||
@@ -702,15 +702,15 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
ssthresh). */
|
||||
if (pcb->state >= ESTABLISHED) {
|
||||
if (pcb->cwnd < pcb->ssthresh) {
|
||||
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
|
||||
pcb->cwnd += pcb->mss;
|
||||
}
|
||||
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
|
||||
pcb->cwnd += pcb->mss;
|
||||
}
|
||||
DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %u\n", pcb->cwnd));
|
||||
} else {
|
||||
u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
|
||||
if (new_cwnd > pcb->cwnd) {
|
||||
pcb->cwnd = new_cwnd;
|
||||
}
|
||||
u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
|
||||
if (new_cwnd > pcb->cwnd) {
|
||||
pcb->cwnd = new_cwnd;
|
||||
}
|
||||
DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));
|
||||
}
|
||||
}
|
||||
@@ -722,27 +722,27 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
|
||||
|
||||
/* Remove segment from the unacknowledged list if the incoming
|
||||
ACK acknowlegdes them. */
|
||||
ACK acknowlegdes them. */
|
||||
while (pcb->unacked != NULL &&
|
||||
TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
|
||||
TCP_TCPLEN(pcb->unacked), ackno)) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
|
||||
ntohl(pcb->unacked->tcphdr->seqno),
|
||||
ntohl(pcb->unacked->tcphdr->seqno) +
|
||||
TCP_TCPLEN(pcb->unacked)));
|
||||
TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
|
||||
TCP_TCPLEN(pcb->unacked), ackno)) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
|
||||
ntohl(pcb->unacked->tcphdr->seqno),
|
||||
ntohl(pcb->unacked->tcphdr->seqno) +
|
||||
TCP_TCPLEN(pcb->unacked)));
|
||||
|
||||
next = pcb->unacked;
|
||||
pcb->unacked = pcb->unacked->next;
|
||||
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %d ... ", pcb->snd_queuelen));
|
||||
pcb->snd_queuelen -= pbuf_clen(next->p);
|
||||
tcp_seg_free(next);
|
||||
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));
|
||||
if (pcb->snd_queuelen != 0) {
|
||||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
||||
pcb->unsent != NULL);
|
||||
}
|
||||
next = pcb->unacked;
|
||||
pcb->unacked = pcb->unacked->next;
|
||||
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %d ... ", pcb->snd_queuelen));
|
||||
pcb->snd_queuelen -= pbuf_clen(next->p);
|
||||
tcp_seg_free(next);
|
||||
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));
|
||||
if (pcb->snd_queuelen != 0) {
|
||||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
||||
pcb->unsent != NULL);
|
||||
}
|
||||
}
|
||||
pcb->polltmr = 0;
|
||||
}
|
||||
@@ -754,25 +754,25 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
->unsent list after a retransmission, so these segments may
|
||||
in fact have been sent once. */
|
||||
while (pcb->unsent != NULL &&
|
||||
TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
|
||||
TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
|
||||
ackno) &&
|
||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n",
|
||||
ntohl(pcb->unsent->tcphdr->seqno),
|
||||
ntohl(pcb->unsent->tcphdr->seqno) +
|
||||
TCP_TCPLEN(pcb->unsent)));
|
||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n",
|
||||
ntohl(pcb->unsent->tcphdr->seqno),
|
||||
ntohl(pcb->unsent->tcphdr->seqno) +
|
||||
TCP_TCPLEN(pcb->unsent)));
|
||||
|
||||
next = pcb->unsent;
|
||||
pcb->unsent = pcb->unsent->next;
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %d ... ", pcb->snd_queuelen));
|
||||
pcb->snd_queuelen -= pbuf_clen(next->p);
|
||||
tcp_seg_free(next);
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));
|
||||
if (pcb->snd_queuelen != 0) {
|
||||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
||||
pcb->unsent != NULL);
|
||||
}
|
||||
|
||||
next = pcb->unsent;
|
||||
pcb->unsent = pcb->unsent->next;
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %d ... ", pcb->snd_queuelen));
|
||||
pcb->snd_queuelen -= pbuf_clen(next->p);
|
||||
tcp_seg_free(next);
|
||||
DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));
|
||||
if (pcb->snd_queuelen != 0) {
|
||||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
||||
pcb->unsent != NULL);
|
||||
}
|
||||
|
||||
if (pcb->unsent != NULL) {
|
||||
pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
|
||||
}
|
||||
@@ -781,7 +781,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
/* End of ACK for new data processing. */
|
||||
|
||||
DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %d rtseq %lu ackno %lu\n",
|
||||
pcb->rttest, pcb->rtseq, ackno));
|
||||
pcb->rttest, pcb->rtseq, ackno));
|
||||
|
||||
/* RTT estimation calculations. This is done by checking if the
|
||||
incoming segment acknowledges the segment we use to take a
|
||||
@@ -790,20 +790,20 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
m = tcp_ticks - pcb->rttest;
|
||||
|
||||
DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %d ticks (%d msec).\n",
|
||||
m, m * TCP_SLOW_INTERVAL));
|
||||
m, m * TCP_SLOW_INTERVAL));
|
||||
|
||||
/* This is taken directly from VJs original code in his paper */
|
||||
m = m - (pcb->sa >> 3);
|
||||
pcb->sa += m;
|
||||
if (m < 0) {
|
||||
m = -m;
|
||||
m = -m;
|
||||
}
|
||||
m = m - (pcb->sv >> 2);
|
||||
pcb->sv += m;
|
||||
pcb->rto = (pcb->sa >> 3) + pcb->sv;
|
||||
|
||||
DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %d (%d miliseconds)\n",
|
||||
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
|
||||
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
|
||||
|
||||
pcb->rttest = 0;
|
||||
}
|
||||
@@ -842,48 +842,48 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
segment is larger than rcv_nxt. */
|
||||
if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
|
||||
if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
|
||||
/* Trimming the first edge is done by pushing the payload
|
||||
pointer in the pbuf downwards. This is somewhat tricky since
|
||||
we do not want to discard the full contents of the pbuf up to
|
||||
the new starting point of the data since we have to keep the
|
||||
TCP header which is present in the first pbuf in the chain.
|
||||
|
||||
What is done is really quite a nasty hack: the first pbuf in
|
||||
the pbuf chain is pointed to by inseg.p. Since we need to be
|
||||
able to deallocate the whole pbuf, we cannot change this
|
||||
inseg.p pointer to point to any of the later pbufs in the
|
||||
chain. Instead, we point the ->payload pointer in the first
|
||||
pbuf to data in one of the later pbufs. We also set the
|
||||
inseg.data pointer to point to the right place. This way, the
|
||||
->p pointer will still point to the first pbuf, but the
|
||||
->p->payload pointer will point to data in another pbuf.
|
||||
|
||||
After we are done with adjusting the pbuf pointers we must
|
||||
adjust the ->data pointer in the seg and the segment
|
||||
length.*/
|
||||
off = pcb->rcv_nxt - seqno;
|
||||
if (inseg.p->len < off) {
|
||||
p = inseg.p;
|
||||
while (p->len < off) {
|
||||
off -= p->len;
|
||||
inseg.p->tot_len -= p->len;
|
||||
p->len = 0;
|
||||
p = p->next;
|
||||
}
|
||||
pbuf_header(p, -off);
|
||||
} else {
|
||||
pbuf_header(inseg.p, -off);
|
||||
}
|
||||
inseg.dataptr = inseg.p->payload;
|
||||
inseg.len -= pcb->rcv_nxt - seqno;
|
||||
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
||||
/* Trimming the first edge is done by pushing the payload
|
||||
pointer in the pbuf downwards. This is somewhat tricky since
|
||||
we do not want to discard the full contents of the pbuf up to
|
||||
the new starting point of the data since we have to keep the
|
||||
TCP header which is present in the first pbuf in the chain.
|
||||
|
||||
What is done is really quite a nasty hack: the first pbuf in
|
||||
the pbuf chain is pointed to by inseg.p. Since we need to be
|
||||
able to deallocate the whole pbuf, we cannot change this
|
||||
inseg.p pointer to point to any of the later pbufs in the
|
||||
chain. Instead, we point the ->payload pointer in the first
|
||||
pbuf to data in one of the later pbufs. We also set the
|
||||
inseg.data pointer to point to the right place. This way, the
|
||||
->p pointer will still point to the first pbuf, but the
|
||||
->p->payload pointer will point to data in another pbuf.
|
||||
|
||||
After we are done with adjusting the pbuf pointers we must
|
||||
adjust the ->data pointer in the seg and the segment
|
||||
length.*/
|
||||
off = pcb->rcv_nxt - seqno;
|
||||
if (inseg.p->len < off) {
|
||||
p = inseg.p;
|
||||
while (p->len < off) {
|
||||
off -= p->len;
|
||||
inseg.p->tot_len -= p->len;
|
||||
p->len = 0;
|
||||
p = p->next;
|
||||
}
|
||||
pbuf_header(p, -off);
|
||||
} else {
|
||||
pbuf_header(inseg.p, -off);
|
||||
}
|
||||
inseg.dataptr = inseg.p->payload;
|
||||
inseg.len -= pcb->rcv_nxt - seqno;
|
||||
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
||||
}
|
||||
else{
|
||||
/* the whole segment is < rcv_nxt */
|
||||
/* must be a duplicate of a packet that has already been correctly handled */
|
||||
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
|
||||
tcp_ack_now(pcb);
|
||||
/* the whole segment is < rcv_nxt */
|
||||
/* must be a duplicate of a packet that has already been correctly handled */
|
||||
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
|
||||
tcp_ack_now(pcb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -892,206 +892,206 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
processed. */
|
||||
if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
|
||||
TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
||||
if (pcb->rcv_nxt == seqno) {
|
||||
/* The incoming segment is the next in sequence. We check if
|
||||
if (pcb->rcv_nxt == seqno) {
|
||||
/* The incoming segment is the next in sequence. We check if
|
||||
we have to trim the end of the segment and update rcv_nxt
|
||||
and pass the data to the application. */
|
||||
#if TCP_QUEUE_OOSEQ
|
||||
if (pcb->ooseq != NULL &&
|
||||
TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
|
||||
/* We have to trim the second edge of the incoming
|
||||
if (pcb->ooseq != NULL &&
|
||||
TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
|
||||
/* We have to trim the second edge of the incoming
|
||||
segment. */
|
||||
inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
|
||||
pbuf_realloc(inseg.p, inseg.len);
|
||||
}
|
||||
inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
|
||||
pbuf_realloc(inseg.p, inseg.len);
|
||||
}
|
||||
#endif /* TCP_QUEUE_OOSEQ */
|
||||
|
||||
tcplen = TCP_TCPLEN(&inseg);
|
||||
|
||||
pcb->rcv_nxt += tcplen;
|
||||
|
||||
/* Update the receiver's (our) window. */
|
||||
if (pcb->rcv_wnd < tcplen) {
|
||||
pcb->rcv_wnd = 0;
|
||||
} else {
|
||||
pcb->rcv_wnd -= tcplen;
|
||||
}
|
||||
|
||||
/* If there is data in the segment, we make preparations to
|
||||
pass this up to the application. The ->recv_data variable
|
||||
is used for holding the pbuf that goes to the
|
||||
application. The code for reassembling out-of-sequence data
|
||||
chains its data on this pbuf as well.
|
||||
|
||||
If the segment was a FIN, we set the TF_GOT_FIN flag that will
|
||||
be used to indicate to the application that the remote side has
|
||||
closed its end of the connection. */
|
||||
if (inseg.p->tot_len > 0) {
|
||||
recv_data = inseg.p;
|
||||
/* Since this pbuf now is the responsibility of the
|
||||
application, we delete our reference to it so that we won't
|
||||
(mistakingly) deallocate it. */
|
||||
inseg.p = NULL;
|
||||
}
|
||||
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
|
||||
recv_flags = TF_GOT_FIN;
|
||||
}
|
||||
|
||||
tcplen = TCP_TCPLEN(&inseg);
|
||||
|
||||
pcb->rcv_nxt += tcplen;
|
||||
|
||||
/* Update the receiver's (our) window. */
|
||||
if (pcb->rcv_wnd < tcplen) {
|
||||
pcb->rcv_wnd = 0;
|
||||
} else {
|
||||
pcb->rcv_wnd -= tcplen;
|
||||
}
|
||||
|
||||
/* If there is data in the segment, we make preparations to
|
||||
pass this up to the application. The ->recv_data variable
|
||||
is used for holding the pbuf that goes to the
|
||||
application. The code for reassembling out-of-sequence data
|
||||
chains its data on this pbuf as well.
|
||||
|
||||
If the segment was a FIN, we set the TF_GOT_FIN flag that will
|
||||
be used to indicate to the application that the remote side has
|
||||
closed its end of the connection. */
|
||||
if (inseg.p->tot_len > 0) {
|
||||
recv_data = inseg.p;
|
||||
/* Since this pbuf now is the responsibility of the
|
||||
application, we delete our reference to it so that we won't
|
||||
(mistakingly) deallocate it. */
|
||||
inseg.p = NULL;
|
||||
}
|
||||
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
|
||||
recv_flags = TF_GOT_FIN;
|
||||
}
|
||||
|
||||
#if TCP_QUEUE_OOSEQ
|
||||
/* We now check if we have segments on the ->ooseq queue that
|
||||
/* We now check if we have segments on the ->ooseq queue that
|
||||
is now in sequence. */
|
||||
while (pcb->ooseq != NULL &&
|
||||
pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
|
||||
while (pcb->ooseq != NULL &&
|
||||
pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
|
||||
|
||||
cseg = pcb->ooseq;
|
||||
seqno = pcb->ooseq->tcphdr->seqno;
|
||||
|
||||
pcb->rcv_nxt += TCP_TCPLEN(cseg);
|
||||
if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
|
||||
pcb->rcv_wnd = 0;
|
||||
} else {
|
||||
pcb->rcv_wnd -= TCP_TCPLEN(cseg);
|
||||
}
|
||||
if (cseg->p->tot_len > 0) {
|
||||
/* Chain this pbuf onto the pbuf that we will pass to
|
||||
the application. */
|
||||
if (recv_data) {
|
||||
cseg = pcb->ooseq;
|
||||
seqno = pcb->ooseq->tcphdr->seqno;
|
||||
|
||||
pcb->rcv_nxt += TCP_TCPLEN(cseg);
|
||||
if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
|
||||
pcb->rcv_wnd = 0;
|
||||
} else {
|
||||
pcb->rcv_wnd -= TCP_TCPLEN(cseg);
|
||||
}
|
||||
if (cseg->p->tot_len > 0) {
|
||||
/* Chain this pbuf onto the pbuf that we will pass to
|
||||
the application. */
|
||||
if (recv_data) {
|
||||
pbuf_chain(recv_data, cseg->p);
|
||||
pbuf_free(cseg->p);
|
||||
} else {
|
||||
recv_data = cseg->p;
|
||||
}
|
||||
cseg->p = NULL;
|
||||
}
|
||||
if (flags & TCP_FIN) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
|
||||
recv_flags = TF_GOT_FIN;
|
||||
}
|
||||
|
||||
recv_data = cseg->p;
|
||||
}
|
||||
cseg->p = NULL;
|
||||
}
|
||||
if (flags & TCP_FIN) {
|
||||
DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
|
||||
recv_flags = TF_GOT_FIN;
|
||||
}
|
||||
|
||||
|
||||
pcb->ooseq = cseg->next;
|
||||
tcp_seg_free(cseg);
|
||||
}
|
||||
pcb->ooseq = cseg->next;
|
||||
tcp_seg_free(cseg);
|
||||
}
|
||||
#endif /* TCP_QUEUE_OOSEQ */
|
||||
|
||||
|
||||
/* Acknowledge the segment(s). */
|
||||
tcp_ack(pcb);
|
||||
/* Acknowledge the segment(s). */
|
||||
tcp_ack(pcb);
|
||||
|
||||
} else {
|
||||
/* We get here if the incoming segment is out-of-sequence. */
|
||||
tcp_ack_now(pcb);
|
||||
/* We get here if the incoming segment is out-of-sequence. */
|
||||
tcp_ack_now(pcb);
|
||||
#if TCP_QUEUE_OOSEQ
|
||||
/* We queue the segment on the ->ooseq queue. */
|
||||
if (pcb->ooseq == NULL) {
|
||||
pcb->ooseq = tcp_seg_copy(&inseg);
|
||||
} else {
|
||||
/* If the queue is not empty, we walk through the queue and
|
||||
try to find a place where the sequence number of the
|
||||
incoming segment is between the sequence numbers of the
|
||||
previous and the next segment on the ->ooseq queue. That is
|
||||
the place where we put the incoming segment. If needed, we
|
||||
trim the second edges of the previous and the incoming
|
||||
segment so that it will fit into the sequence.
|
||||
/* We queue the segment on the ->ooseq queue. */
|
||||
if (pcb->ooseq == NULL) {
|
||||
pcb->ooseq = tcp_seg_copy(&inseg);
|
||||
} else {
|
||||
/* If the queue is not empty, we walk through the queue and
|
||||
try to find a place where the sequence number of the
|
||||
incoming segment is between the sequence numbers of the
|
||||
previous and the next segment on the ->ooseq queue. That is
|
||||
the place where we put the incoming segment. If needed, we
|
||||
trim the second edges of the previous and the incoming
|
||||
segment so that it will fit into the sequence.
|
||||
|
||||
If the incoming segment has the same sequence number as a
|
||||
segment on the ->ooseq queue, we discard the segment that
|
||||
contains less data. */
|
||||
If the incoming segment has the same sequence number as a
|
||||
segment on the ->ooseq queue, we discard the segment that
|
||||
contains less data. */
|
||||
|
||||
prev = NULL;
|
||||
for(next = pcb->ooseq; next != NULL; next = next->next) {
|
||||
if (seqno == next->tcphdr->seqno) {
|
||||
/* The sequence number of the incoming segment is the
|
||||
prev = NULL;
|
||||
for(next = pcb->ooseq; next != NULL; next = next->next) {
|
||||
if (seqno == next->tcphdr->seqno) {
|
||||
/* The sequence number of the incoming segment is the
|
||||
same as the sequence number of the segment on
|
||||
->ooseq. We check the lengths to see which one to
|
||||
discard. */
|
||||
if (inseg.len > next->len) {
|
||||
/* The incoming segment is larger than the old
|
||||
if (inseg.len > next->len) {
|
||||
/* The incoming segment is larger than the old
|
||||
segment. We replace the old segment with the new
|
||||
one. */
|
||||
cseg = tcp_seg_copy(&inseg);
|
||||
if (cseg != NULL) {
|
||||
cseg->next = next->next;
|
||||
if (prev != NULL) {
|
||||
prev->next = cseg;
|
||||
} else {
|
||||
pcb->ooseq = cseg;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
/* Either the lenghts are the same or the incoming
|
||||
cseg = tcp_seg_copy(&inseg);
|
||||
if (cseg != NULL) {
|
||||
cseg->next = next->next;
|
||||
if (prev != NULL) {
|
||||
prev->next = cseg;
|
||||
} else {
|
||||
pcb->ooseq = cseg;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
/* Either the lenghts are the same or the incoming
|
||||
segment was smaller than the old one; in either
|
||||
case, we ditch the incoming segment. */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (prev == NULL) {
|
||||
if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
|
||||
/* The sequence number of the incoming segment is lower
|
||||
than the sequence number of the first segment on the
|
||||
queue. We put the incoming segment first on the
|
||||
queue. */
|
||||
|
||||
if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
|
||||
/* We need to trim the incoming segment. */
|
||||
inseg.len = next->tcphdr->seqno - seqno;
|
||||
pbuf_realloc(inseg.p, inseg.len);
|
||||
}
|
||||
cseg = tcp_seg_copy(&inseg);
|
||||
if (cseg != NULL) {
|
||||
cseg->next = next;
|
||||
pcb->ooseq = cseg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
|
||||
TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
|
||||
/* The sequence number of the incoming segment is in
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (prev == NULL) {
|
||||
if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
|
||||
/* The sequence number of the incoming segment is lower
|
||||
than the sequence number of the first segment on the
|
||||
queue. We put the incoming segment first on the
|
||||
queue. */
|
||||
|
||||
if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
|
||||
/* We need to trim the incoming segment. */
|
||||
inseg.len = next->tcphdr->seqno - seqno;
|
||||
pbuf_realloc(inseg.p, inseg.len);
|
||||
}
|
||||
cseg = tcp_seg_copy(&inseg);
|
||||
if (cseg != NULL) {
|
||||
cseg->next = next;
|
||||
pcb->ooseq = cseg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
|
||||
TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
|
||||
/* The sequence number of the incoming segment is in
|
||||
between the sequence numbers of the previous and
|
||||
the next segment on ->ooseq. We trim and insert the
|
||||
incoming segment and trim the previous segment, if
|
||||
needed. */
|
||||
if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
|
||||
/* We need to trim the incoming segment. */
|
||||
inseg.len = next->tcphdr->seqno - seqno;
|
||||
pbuf_realloc(inseg.p, inseg.len);
|
||||
}
|
||||
if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
|
||||
/* We need to trim the incoming segment. */
|
||||
inseg.len = next->tcphdr->seqno - seqno;
|
||||
pbuf_realloc(inseg.p, inseg.len);
|
||||
}
|
||||
|
||||
cseg = tcp_seg_copy(&inseg);
|
||||
if (cseg != NULL) {
|
||||
cseg->next = next;
|
||||
prev->next = cseg;
|
||||
if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
|
||||
/* We need to trim the prev segment. */
|
||||
prev->len = seqno - prev->tcphdr->seqno;
|
||||
pbuf_realloc(prev->p, prev->len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* If the "next" segment is the last segment on the
|
||||
cseg = tcp_seg_copy(&inseg);
|
||||
if (cseg != NULL) {
|
||||
cseg->next = next;
|
||||
prev->next = cseg;
|
||||
if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
|
||||
/* We need to trim the prev segment. */
|
||||
prev->len = seqno - prev->tcphdr->seqno;
|
||||
pbuf_realloc(prev->p, prev->len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* If the "next" segment is the last segment on the
|
||||
ooseq queue, we add the incoming segment to the end
|
||||
of the list. */
|
||||
if (next->next == NULL &&
|
||||
TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
|
||||
next->next = tcp_seg_copy(&inseg);
|
||||
if (next->next != NULL) {
|
||||
if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
|
||||
/* We need to trim the last segment. */
|
||||
next->len = seqno - next->tcphdr->seqno;
|
||||
pbuf_realloc(next->p, next->len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev = next;
|
||||
}
|
||||
}
|
||||
if (next->next == NULL &&
|
||||
TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
|
||||
next->next = tcp_seg_copy(&inseg);
|
||||
if (next->next != NULL) {
|
||||
if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
|
||||
/* We need to trim the last segment. */
|
||||
next->len = seqno - next->tcphdr->seqno;
|
||||
pbuf_realloc(next->p, next->len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
prev = next;
|
||||
}
|
||||
}
|
||||
#endif /* TCP_QUEUE_OOSEQ */
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1127,7 +1127,7 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
||||
opt = opts[c];
|
||||
if (opt == 0x00) {
|
||||
/* End of options. */
|
||||
break;
|
||||
break;
|
||||
} else if (opt == 0x01) {
|
||||
++c;
|
||||
/* NOP option. */
|
||||
@@ -1140,7 +1140,7 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
||||
/* And we are done processing options. */
|
||||
break;
|
||||
} else {
|
||||
if (opts[c + 1] == 0) {
|
||||
if (opts[c + 1] == 0) {
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
|
||||
@@ -92,7 +92,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||
u8_t flags, u8_t copy,
|
||||
u8_t flags, u8_t copy,
|
||||
u8_t *optdata, u8_t optlen)
|
||||
{
|
||||
struct pbuf *p;
|
||||
@@ -173,7 +173,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||
}
|
||||
else if (copy) {
|
||||
if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %u\n", seglen));
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %u\n", seglen));
|
||||
goto memerr;
|
||||
}
|
||||
++queuelen;
|
||||
@@ -191,7 +191,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||
* instead of PBUF_REF here.
|
||||
*/
|
||||
if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
|
||||
goto memerr;
|
||||
}
|
||||
++queuelen;
|
||||
@@ -203,7 +203,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||
/* If allocation fails, we have to deallocate the data pbuf as
|
||||
* well. */
|
||||
pbuf_free(p);
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
|
||||
goto memerr;
|
||||
}
|
||||
++queuelen;
|
||||
@@ -217,7 +217,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||
/* Now that there are more segments queued, we check again if the
|
||||
length of the queue exceeds the configured maximum. */
|
||||
if (queuelen > TCP_SND_QUEUELEN) {
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));
|
||||
DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));
|
||||
goto memerr;
|
||||
}
|
||||
|
||||
@@ -400,10 +400,10 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
|
||||
tcphdr->chksum = 0;
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
|
||||
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL,
|
||||
IP_PROTO_TCP);
|
||||
IP_PROTO_TCP);
|
||||
pbuf_free(p);
|
||||
|
||||
return ERR_OK;
|
||||
@@ -428,7 +428,7 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
#endif /* TCP_CWND_DEBUG */
|
||||
|
||||
while (seg != NULL &&
|
||||
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
|
||||
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
|
||||
#if TCP_CWND_DEBUG
|
||||
DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %lu, cwnd %lu, wnd %lu, effwnd %lu, seq %lu, ack %lu, i%d\n",
|
||||
pcb->snd_wnd, pcb->cwnd, wnd,
|
||||
@@ -455,8 +455,8 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
seg->next = NULL;
|
||||
if (pcb->unacked == NULL) {
|
||||
pcb->unacked = seg;
|
||||
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
for (useg = pcb->unacked; useg->next != NULL; useg = useg->next);
|
||||
useg->next = seg;
|
||||
@@ -506,8 +506,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %lu\n", pcb->rtseq));
|
||||
}
|
||||
DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %lu:%lu\n",
|
||||
htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
|
||||
seg->len));
|
||||
htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) +
|
||||
seg->len));
|
||||
|
||||
len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
|
||||
|
||||
@@ -518,21 +518,21 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
|
||||
seg->tcphdr->chksum = 0;
|
||||
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
|
||||
&(pcb->local_ip),
|
||||
&(pcb->remote_ip),
|
||||
IP_PROTO_TCP, seg->p->tot_len);
|
||||
&(pcb->local_ip),
|
||||
&(pcb->remote_ip),
|
||||
IP_PROTO_TCP, seg->p->tot_len);
|
||||
#ifdef TCP_STATS
|
||||
++lwip_stats.tcp.xmit;
|
||||
#endif /* TCP_STATS */
|
||||
|
||||
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), TCP_TTL,
|
||||
IP_PROTO_TCP);
|
||||
IP_PROTO_TCP);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
tcp_rst(u32_t seqno, u32_t ackno,
|
||||
struct ip_addr *local_ip, struct ip_addr *remote_ip,
|
||||
u16_t local_port, u16_t remote_port)
|
||||
struct ip_addr *local_ip, struct ip_addr *remote_ip,
|
||||
u16_t local_port, u16_t remote_port)
|
||||
{
|
||||
struct pbuf *p;
|
||||
struct tcp_hdr *tcphdr;
|
||||
@@ -554,7 +554,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
||||
|
||||
tcphdr->chksum = 0;
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
|
||||
#ifdef TCP_STATS
|
||||
++lwip_stats.tcp.xmit;
|
||||
|
||||
229
src/core/udp.c
229
src/core/udp.c
@@ -5,9 +5,9 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
@@ -16,21 +16,21 @@
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ static struct udp_pcb *pcb_cache = NULL;
|
||||
#if UDP_DEBUG
|
||||
int udp_debug_print(struct udp_hdr *udphdr);
|
||||
#endif /* UDP_DEBUG */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
udp_init(void)
|
||||
@@ -108,28 +108,28 @@ udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
else {
|
||||
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->remote_port == src &&
|
||||
pcb->local_port == dest &&
|
||||
(ip_addr_isany(&pcb->remote_ip) ||
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
pcb_cache = pcb;
|
||||
pcb->local_port == dest &&
|
||||
(ip_addr_isany(&pcb->remote_ip) ||
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
pcb_cache = pcb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcb == NULL) {
|
||||
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->remote_port == 0 &&
|
||||
pcb->local_port == dest &&
|
||||
(ip_addr_isany(&pcb->remote_ip) ||
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
break;
|
||||
if (pcb->remote_port == 0 &&
|
||||
pcb->local_port == dest &&
|
||||
(ip_addr_isany(&pcb->remote_ip) ||
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,7 +140,7 @@ udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
|
||||
if (pcb != NULL) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -154,18 +154,17 @@ udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
|
||||
* @param pbuf pbuf to be demultiplexed to a UDP PCB.
|
||||
* @param netif network interface on which the datagram was received.
|
||||
*
|
||||
* @see udp_disconnect()
|
||||
*/
|
||||
void
|
||||
udp_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
struct udp_hdr *udphdr;
|
||||
struct udp_hdr *udphdr;
|
||||
struct udp_pcb *pcb;
|
||||
struct ip_hdr *iphdr;
|
||||
u16_t src, dest;
|
||||
|
||||
|
||||
PERF_START;
|
||||
|
||||
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.recv;
|
||||
#endif /* UDP_STATS */
|
||||
@@ -174,20 +173,20 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {
|
||||
/* drop short packets */
|
||||
DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));
|
||||
DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.lenerr;
|
||||
++lwip_stats.udp.drop;
|
||||
++lwip_stats.udp.lenerr;
|
||||
++lwip_stats.udp.drop;
|
||||
#endif /* UDP_STATS */
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
|
||||
udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
|
||||
|
||||
|
||||
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
|
||||
|
||||
|
||||
src = ntohs(udphdr->src);
|
||||
dest = ntohs(udphdr->dest);
|
||||
|
||||
@@ -217,11 +216,11 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
/* accepting from any remote (source) IP address? or... */
|
||||
(ip_addr_isany(&pcb->remote_ip) ||
|
||||
/* PCB remote IP address matches UDP source IP address? */
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
||||
/* accepting on any local (netif) IP address? or... */
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
/* PCB local IP address matches UDP destination IP address? */
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -237,73 +236,73 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
|
||||
/* unconnected? */
|
||||
if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&
|
||||
/* destination port matches? */
|
||||
(pcb->local_port == dest) &&
|
||||
/* not bound to a specific (local) interface address? or... */
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
/* ...matching interface address? */
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
break;
|
||||
}
|
||||
/* destination port matches? */
|
||||
(pcb->local_port == dest) &&
|
||||
/* not bound to a specific (local) interface address? or... */
|
||||
(ip_addr_isany(&pcb->local_ip) ||
|
||||
/* ...matching interface address? */
|
||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check checksum if this is a match or if it was directed at us. */
|
||||
if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
|
||||
if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
|
||||
{
|
||||
DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
|
||||
pbuf_header(p, UDP_HLEN);
|
||||
pbuf_header(p, UDP_HLEN);
|
||||
#ifdef IPv6
|
||||
if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
|
||||
if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
|
||||
#else
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
|
||||
#endif /* IPv4 */
|
||||
/* Do the UDP Lite checksum */
|
||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
|
||||
DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
|
||||
DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.chkerr;
|
||||
++lwip_stats.udp.drop;
|
||||
++lwip_stats.udp.chkerr;
|
||||
++lwip_stats.udp.drop;
|
||||
#endif /* UDP_STATS */
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (udphdr->chksum != 0) {
|
||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_UDP, p->tot_len) != 0) {
|
||||
DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
|
||||
|
||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||
(struct ip_addr *)&(iphdr->dest),
|
||||
IP_PROTO_UDP, p->tot_len) != 0) {
|
||||
DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
|
||||
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.chkerr;
|
||||
++lwip_stats.udp.drop;
|
||||
++lwip_stats.udp.chkerr;
|
||||
++lwip_stats.udp.drop;
|
||||
#endif /* UDP_STATS */
|
||||
snmp_inc_udpinerrors();
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
pbuf_free(p);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
pbuf_header(p, -UDP_HLEN);
|
||||
pbuf_header(p, -UDP_HLEN);
|
||||
if (pcb != NULL) {
|
||||
snmp_inc_udpindatagrams();
|
||||
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
|
||||
} else {
|
||||
DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
|
||||
|
||||
|
||||
/* No match was found, send ICMP destination port unreachable unless
|
||||
destination address was broadcast/multicast. */
|
||||
|
||||
destination address was broadcast/multicast. */
|
||||
|
||||
if (!ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) &&
|
||||
!ip_addr_ismulticast(&iphdr->dest)) {
|
||||
|
||||
/* adjust pbuf pointer */
|
||||
p->payload = iphdr;
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
!ip_addr_ismulticast(&iphdr->dest)) {
|
||||
|
||||
/* adjust pbuf pointer */
|
||||
p->payload = iphdr;
|
||||
icmp_dest_unreach(p, ICMP_DUR_PORT);
|
||||
}
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.proterr;
|
||||
@@ -316,11 +315,11 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
pbuf_free(p);
|
||||
}
|
||||
end:
|
||||
|
||||
|
||||
PERF_STOP("udp_input");
|
||||
}
|
||||
/**
|
||||
* Send data using UDP.
|
||||
* Send data using UDP.
|
||||
*
|
||||
* @param pcb UDP PCB used to send the data.
|
||||
* @param pbuf chain of pbuf's to be sent.
|
||||
@@ -330,7 +329,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
* - ERR_MEM. Out of memory.
|
||||
* - ERR_USE. The specified ipaddr and port are already bound to by
|
||||
* another UDP PCB.
|
||||
*
|
||||
*
|
||||
* @see udp_disconnect()
|
||||
*/
|
||||
err_t
|
||||
@@ -368,7 +367,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* { first pbuf q points to header pbuf } */
|
||||
DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||
/* adding a header within p succeeded */
|
||||
} else {
|
||||
} else {
|
||||
/* first pbuf q equals given pbuf */
|
||||
q = p;
|
||||
DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
|
||||
@@ -394,9 +393,9 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* use UDP PCB local IP address as source address */
|
||||
src_ip = &(pcb->local_ip);
|
||||
}
|
||||
|
||||
|
||||
DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
|
||||
|
||||
|
||||
/* UDP Lite protocol? */
|
||||
if (pcb->flags & UDP_FLAGS_UDPLITE) {
|
||||
DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));
|
||||
@@ -404,11 +403,11 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
udphdr->len = htons(pcb->chksum_len);
|
||||
/* calculate checksum */
|
||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
|
||||
IP_PROTO_UDP, pcb->chksum_len);
|
||||
IP_PROTO_UDP, pcb->chksum_len);
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
||||
/* output to IP */
|
||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDPLITE, netif);
|
||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDPLITE, netif);
|
||||
snmp_inc_udpoutdatagrams();
|
||||
} else {
|
||||
DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
|
||||
@@ -423,7 +422,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
snmp_inc_udpoutdatagrams();
|
||||
DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
||||
/* output to IP */
|
||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif);
|
||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif);
|
||||
}
|
||||
|
||||
/* did we chain a header earlier? */
|
||||
@@ -431,7 +430,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* free the header */
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.xmit;
|
||||
#endif /* UDP_STATS */
|
||||
@@ -450,7 +449,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
* - ERR_OK. Successful. No error occured.
|
||||
* - ERR_USE. The specified ipaddr and port are already bound to by
|
||||
* another UDP PCB.
|
||||
*
|
||||
*
|
||||
* @see udp_disconnect()
|
||||
*/
|
||||
err_t
|
||||
@@ -462,27 +461,27 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
rebind = 0;
|
||||
/* Check for double bind and rebind of the same pcb */
|
||||
for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
|
||||
/* is this UDP PCB already on active list? */
|
||||
/* is this UDP PCB already on active list? */
|
||||
if (pcb == ipcb) {
|
||||
/* pcb may occur at most once in active list */
|
||||
LWIP_ASSERT("rebind == 0", rebind == 0);
|
||||
/* pcb already in list, just rebind */
|
||||
rebind = 1;
|
||||
rebind = 1;
|
||||
}
|
||||
/* this code does not allow upper layer to share a UDP port for
|
||||
listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
|
||||
SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
|
||||
combine with implementation of UDP PCB flags. Leon Woestenberg. */
|
||||
#if 0
|
||||
#if 0
|
||||
/* port matches that of PCB in list? */
|
||||
else if ((ipcb->local_port == port) &&
|
||||
/* IP address matches, or one is IP_ADDR_ANY? */
|
||||
(ip_addr_isany(&(ipcb->local_ip)) ||
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
|
||||
ip_addr_isany(ipaddr) ||
|
||||
ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
|
||||
/* other PCB already binds to this local IP and port */
|
||||
DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));
|
||||
return ERR_USE;
|
||||
return ERR_USE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -501,13 +500,13 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
port++;
|
||||
ipcb = udp_pcbs;
|
||||
} else
|
||||
ipcb = ipcb->next;
|
||||
ipcb = ipcb->next;
|
||||
}
|
||||
if (ipcb != NULL) {
|
||||
/* no more ports available in local range */
|
||||
DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
|
||||
return ERR_USE;
|
||||
}
|
||||
}
|
||||
}
|
||||
pcb->local_port = port;
|
||||
/* pcb not active yet? */
|
||||
@@ -515,7 +514,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
/* place the PCB on the active list if not already there */
|
||||
pcb->next = udp_pcbs;
|
||||
udp_pcbs = pcb;
|
||||
}
|
||||
}
|
||||
DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
|
||||
(u8_t)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
|
||||
(u8_t)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
|
||||
@@ -533,7 +532,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
* @param port remote UDP port to connect with.
|
||||
*
|
||||
* @return lwIP error code
|
||||
*
|
||||
*
|
||||
* @see udp_disconnect()
|
||||
*/
|
||||
err_t
|
||||
@@ -553,21 +552,21 @@ udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
/** TODO: this functionality belongs in upper layers */
|
||||
#if 0
|
||||
/* Nail down local IP for netconn_addr()/getsockname() */
|
||||
if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
|
||||
if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
|
||||
struct netif *netif;
|
||||
|
||||
if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
|
||||
DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
|
||||
DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
|
||||
#ifdef UDP_STATS
|
||||
++lwip_stats.udp.rterr;
|
||||
#endif /* UDP_STATS */
|
||||
return ERR_RTE;
|
||||
return ERR_RTE;
|
||||
}
|
||||
/** TODO: this will bind the udp pcb locally, to the interface which
|
||||
is used to route output packets to the remote address. However, we
|
||||
might want to accept incoming packets on any interface! */
|
||||
pcb->local_ip = netif->ip_addr;
|
||||
} else if (ip_addr_isany(&pcb->remote_ip)) {
|
||||
} else if (ip_addr_isany(&pcb->remote_ip)) {
|
||||
pcb->local_ip.addr = 0;
|
||||
}
|
||||
#endif
|
||||
@@ -593,14 +592,14 @@ udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||
void
|
||||
udp_disconnect(struct udp_pcb *pcb)
|
||||
{
|
||||
pcb->flags &= ~UDP_FLAGS_CONNECTED;
|
||||
pcb->flags &= ~UDP_FLAGS_CONNECTED;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
udp_recv(struct udp_pcb *pcb,
|
||||
void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
|
||||
struct ip_addr *addr, u16_t port),
|
||||
void *recv_arg)
|
||||
void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
|
||||
struct ip_addr *addr, u16_t port),
|
||||
void *recv_arg)
|
||||
{
|
||||
/* remember recv() callback and user data */
|
||||
pcb->recv = recv;
|
||||
@@ -611,7 +610,7 @@ udp_recv(struct udp_pcb *pcb,
|
||||
*
|
||||
* @param pcb UDP PCB to be removed. The PCB is removed from the list of
|
||||
* UDP PCB's and the data structure is freed from memory.
|
||||
*
|
||||
*
|
||||
* @see udp_new()
|
||||
*/
|
||||
void
|
||||
@@ -630,14 +629,14 @@ udp_remove(struct udp_pcb *pcb)
|
||||
pcb2->next = pcb->next;
|
||||
}
|
||||
}
|
||||
memp_free(MEMP_UDP_PCB, pcb);
|
||||
memp_free(MEMP_UDP_PCB, pcb);
|
||||
}
|
||||
/**
|
||||
* Create a UDP PCB.
|
||||
*
|
||||
* @return The UDP PCB which was created. NULL if the PCB data structure
|
||||
* could not be allocated.
|
||||
*
|
||||
*
|
||||
* @see udp_remove()
|
||||
*/
|
||||
struct udp_pcb *
|
||||
@@ -659,10 +658,10 @@ udp_debug_print(struct udp_hdr *udphdr)
|
||||
DEBUGF(UDP_DEBUG, ("UDP header:\n"));
|
||||
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(UDP_DEBUG, ("| %5u | %5u | (src port, dest port)\n",
|
||||
ntohs(udphdr->src), ntohs(udphdr->dest)));
|
||||
ntohs(udphdr->src), ntohs(udphdr->dest)));
|
||||
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
|
||||
DEBUGF(UDP_DEBUG, ("| %5u | 0x%04x | (len, chksum)\n",
|
||||
ntohs(udphdr->len), ntohs(udphdr->chksum)));
|
||||
ntohs(udphdr->len), ntohs(udphdr->chksum)));
|
||||
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user