mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-12-10 08:46:40 +08:00
Applied Patch #1326 (TCP: readability, debugging, performance fixes by floriZ)
with various improvements and adaptations.
This commit is contained in:
parent
cea3ff9d38
commit
77eea999d9
@ -1038,24 +1038,24 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
|
|||||||
{
|
{
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("| %04x | %04x | (src port, dest port)\n",
|
LWIP_DEBUGF(TCP_DEBUG, ("| %5u | %5u | (src port, dest port)\n",
|
||||||
tcphdr->src, tcphdr->dest));
|
ntohs(tcphdr->src), ntohs(tcphdr->dest)));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("| %08lu | (seq no)\n",
|
LWIP_DEBUGF(TCP_DEBUG, ("| %010lu | (seq no)\n",
|
||||||
tcphdr->seqno));
|
ntohl(tcphdr->seqno)));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("| %08lu | (ack no)\n",
|
LWIP_DEBUGF(TCP_DEBUG, ("| %010lu | (ack no)\n",
|
||||||
tcphdr->ackno));
|
ntohl(tcphdr->ackno)));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("| %2u | |%u%u%u%u%u| %5u | (offset, flags (",
|
LWIP_DEBUGF(TCP_DEBUG, ("| %2u | |%u%u%u%u%u%u| %5u | (hdrlen, flags (",
|
||||||
TCPH_OFFSET(tcphdr),
|
TCPH_HDRLEN(tcphdr),
|
||||||
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
TCPH_FLAGS(tcphdr) >> 5 & 1,
|
||||||
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
TCPH_FLAGS(tcphdr) >> 4 & 1,
|
||||||
TCPH_FLAGS(tcphdr) >> 3 & 1,
|
TCPH_FLAGS(tcphdr) >> 3 & 1,
|
||||||
TCPH_FLAGS(tcphdr) >> 2 & 1,
|
TCPH_FLAGS(tcphdr) >> 2 & 1,
|
||||||
TCPH_FLAGS(tcphdr) >> 1 & 1,
|
TCPH_FLAGS(tcphdr) >> 1 & 1,
|
||||||
TCPH_FLAGS(tcphdr) & 1,
|
TCPH_FLAGS(tcphdr) & 1,
|
||||||
tcphdr->wnd));
|
ntohs(tcphdr->wnd)));
|
||||||
tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
|
tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
|
||||||
|
|||||||
@ -99,7 +99,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
{
|
{
|
||||||
struct tcp_pcb *pcb, *prev;
|
struct tcp_pcb *pcb, *prev;
|
||||||
struct tcp_pcb_listen *lpcb;
|
struct tcp_pcb_listen *lpcb;
|
||||||
u8_t offset;
|
u8_t hdrlen;
|
||||||
err_t err;
|
err_t err;
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +113,10 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||||
|
|
||||||
|
#if TCP_INPUT_DEBUG
|
||||||
|
tcp_debug_print(tcphdr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* remove header from payload */
|
/* remove header from payload */
|
||||||
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
|
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
|
||||||
/* drop short packets */
|
/* drop short packets */
|
||||||
@ -154,8 +158,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
/* Move the payload pointer in the pbuf so that it points to the
|
/* Move the payload pointer in the pbuf so that it points to the
|
||||||
TCP data instead of the TCP header. */
|
TCP data instead of the TCP header. */
|
||||||
offset = TCPH_OFFSET(tcphdr) >> 4;
|
hdrlen = TCPH_HDRLEN(tcphdr);
|
||||||
pbuf_header(p, -(offset * 4));
|
pbuf_header(p, -(hdrlen * 4));
|
||||||
|
|
||||||
/* Convert fields in TCP header to host byte order. */
|
/* Convert fields in TCP header to host byte order. */
|
||||||
tcphdr->src = ntohs(tcphdr->src);
|
tcphdr->src = ntohs(tcphdr->src);
|
||||||
@ -934,7 +938,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
inseg.p = NULL;
|
inseg.p = NULL;
|
||||||
}
|
}
|
||||||
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
|
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags = TF_GOT_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,7 +969,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
cseg->p = NULL;
|
cseg->p = NULL;
|
||||||
}
|
}
|
||||||
if (flags & TCP_FIN) {
|
if (flags & TCP_FIN) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags = TF_GOT_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,8 +1126,8 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
|||||||
opts = (u8_t *)tcphdr + TCP_HLEN;
|
opts = (u8_t *)tcphdr + TCP_HLEN;
|
||||||
|
|
||||||
/* Parse the TCP MSS option, if present. */
|
/* Parse the TCP MSS option, if present. */
|
||||||
if ((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {
|
if(TCPH_HDRLEN(tcphdr) > 0x5) {
|
||||||
for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {
|
for(c = 0; c < (TCPH_HDRLEN(tcphdr) - 5) << 2 ;) {
|
||||||
opt = opts[c];
|
opt = opts[c];
|
||||||
if (opt == 0x00) {
|
if (opt == 0x00) {
|
||||||
/* End of options. */
|
/* End of options. */
|
||||||
|
|||||||
@ -249,10 +249,10 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
|
|
||||||
/* Copy the options into the header, if they are present. */
|
/* Copy the options into the header, if they are present. */
|
||||||
if (optdata == NULL) {
|
if (optdata == NULL) {
|
||||||
TCPH_OFFSET_SET(seg->tcphdr, 5 << 4);
|
TCPH_HDRLEN_SET(seg->tcphdr, 5);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TCPH_OFFSET_SET(seg->tcphdr, (5 + optlen / 4) << 4);
|
TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4));
|
||||||
/* Copy options into data portion of segment.
|
/* Copy options into data portion of segment.
|
||||||
Options can thus only be sent in non data carrying
|
Options can thus only be sent in non data carrying
|
||||||
segments such as SYN|ACK. */
|
segments such as SYN|ACK. */
|
||||||
@ -327,7 +327,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
/* Set the PSH flag in the last segment that we enqueued, but only
|
/* Set the PSH flag in the last segment that we enqueued, but only
|
||||||
if the segment has data (indicated by seglen > 0). */
|
if the segment has data (indicated by seglen > 0). */
|
||||||
if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) {
|
if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) {
|
||||||
TCPH_FLAGS_SET(seg->tcphdr, TCPH_FLAGS(seg->tcphdr) | TCP_PSH);
|
TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
@ -372,6 +372,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
|
|
||||||
seg = pcb->unsent;
|
seg = pcb->unsent;
|
||||||
|
useg = pcb->unacked;
|
||||||
|
|
||||||
/* If the TF_ACK_NOW flag is set, we check if there is data that is
|
/* If the TF_ACK_NOW flag is set, we check if there is data that is
|
||||||
to be sent. If data is to be sent out, we'll just piggyback our
|
to be sent. If data is to be sent out, we'll just piggyback our
|
||||||
@ -398,7 +399,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
TCPH_FLAGS_SET(tcphdr, TCP_ACK);
|
TCPH_FLAGS_SET(tcphdr, TCP_ACK);
|
||||||
tcphdr->wnd = htons(pcb->rcv_wnd);
|
tcphdr->wnd = htons(pcb->rcv_wnd);
|
||||||
tcphdr->urgp = 0;
|
tcphdr->urgp = 0;
|
||||||
TCPH_OFFSET_SET(tcphdr, 5 << 4);
|
TCPH_HDRLEN_SET(tcphdr, 5);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
||||||
@ -443,7 +444,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
pcb->unsent = seg->next;
|
pcb->unsent = seg->next;
|
||||||
|
|
||||||
if (pcb->state != SYN_SENT) {
|
if (pcb->state != SYN_SENT) {
|
||||||
TCPH_FLAGS_SET(seg->tcphdr, TCPH_FLAGS(seg->tcphdr) | TCP_ACK);
|
TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
|
||||||
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,11 +458,10 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
seg->next = NULL;
|
seg->next = NULL;
|
||||||
if (pcb->unacked == NULL) {
|
if (pcb->unacked == NULL) {
|
||||||
pcb->unacked = seg;
|
pcb->unacked = seg;
|
||||||
|
useg = seg;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (useg = pcb->unacked; useg->next != NULL; useg = useg->next);
|
|
||||||
useg->next = seg;
|
useg->next = seg;
|
||||||
|
useg = useg->next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tcp_seg_free(seg);
|
tcp_seg_free(seg);
|
||||||
@ -552,7 +552,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
|||||||
TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
|
TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK);
|
||||||
tcphdr->wnd = htons(TCP_WND);
|
tcphdr->wnd = htons(TCP_WND);
|
||||||
tcphdr->urgp = 0;
|
tcphdr->urgp = 0;
|
||||||
TCPH_OFFSET_SET(tcphdr, 5 << 4);
|
TCPH_HDRLEN_SET(tcphdr, 5);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
||||||
|
|||||||
@ -158,7 +158,7 @@ struct tcp_hdr {
|
|||||||
PACK_STRUCT_FIELD(u16_t dest);
|
PACK_STRUCT_FIELD(u16_t dest);
|
||||||
PACK_STRUCT_FIELD(u32_t seqno);
|
PACK_STRUCT_FIELD(u32_t seqno);
|
||||||
PACK_STRUCT_FIELD(u32_t ackno);
|
PACK_STRUCT_FIELD(u32_t ackno);
|
||||||
PACK_STRUCT_FIELD(u16_t _offset_flags);
|
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
|
||||||
PACK_STRUCT_FIELD(u16_t wnd);
|
PACK_STRUCT_FIELD(u16_t wnd);
|
||||||
PACK_STRUCT_FIELD(u16_t chksum);
|
PACK_STRUCT_FIELD(u16_t chksum);
|
||||||
PACK_STRUCT_FIELD(u16_t urgp);
|
PACK_STRUCT_FIELD(u16_t urgp);
|
||||||
@ -168,11 +168,15 @@ PACK_STRUCT_END
|
|||||||
# include "arch/epstruct.h"
|
# include "arch/epstruct.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TCPH_OFFSET(hdr) (ntohs((hdr)->_offset_flags) >> 8)
|
#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
|
||||||
#define TCPH_FLAGS(hdr) (ntohs((hdr)->_offset_flags) & 0xff)
|
#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
|
||||||
|
#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
|
||||||
|
|
||||||
#define TCPH_OFFSET_SET(hdr, offset) (hdr)->_offset_flags = htons(((offset) << 8) | TCPH_FLAGS(hdr))
|
#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
|
||||||
#define TCPH_FLAGS_SET(hdr, flags) (hdr)->_offset_flags = htons((TCPH_OFFSET(hdr) << 8) | (flags))
|
#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
|
||||||
|
#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
|
||||||
|
#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
|
||||||
|
#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
|
||||||
|
|
||||||
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
|
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
|
||||||
TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
|
TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
|
||||||
@ -219,12 +223,12 @@ struct tcp_pcb {
|
|||||||
u16_t mss; /* maximum segment size */
|
u16_t mss; /* maximum segment size */
|
||||||
|
|
||||||
u8_t flags;
|
u8_t flags;
|
||||||
#define TF_ACK_DELAY 0x01U /* Delayed ACK. */
|
#define TF_ACK_DELAY (u8_t)0x01U /* Delayed ACK. */
|
||||||
#define TF_ACK_NOW 0x02U /* Immediate ACK. */
|
#define TF_ACK_NOW (u8_t)0x02U /* Immediate ACK. */
|
||||||
#define TF_INFR 0x04U /* In fast recovery. */
|
#define TF_INFR (u8_t)0x04U /* In fast recovery. */
|
||||||
#define TF_RESET 0x08U /* Connection was reset. */
|
#define TF_RESET (u8_t)0x08U /* Connection was reset. */
|
||||||
#define TF_CLOSED 0x10U /* Connection was sucessfully closed. */
|
#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */
|
||||||
#define TF_GOT_FIN 0x20U /* Connection was closed by the remote end. */
|
#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */
|
||||||
|
|
||||||
/* RTT estimation variables. */
|
/* RTT estimation variables. */
|
||||||
u16_t rttest; /* RTT estimate in 500ms ticks */
|
u16_t rttest; /* RTT estimate in 500ms ticks */
|
||||||
@ -406,6 +410,10 @@ void tcp_debug_print_state(enum tcp_state s);
|
|||||||
void tcp_debug_print_pcbs(void);
|
void tcp_debug_print_pcbs(void);
|
||||||
int tcp_pcbs_sane(void);
|
int tcp_pcbs_sane(void);
|
||||||
#else
|
#else
|
||||||
|
# define tcp_debug_print(tcphdr)
|
||||||
|
# define tcp_debug_print_flags(flags)
|
||||||
|
# define tcp_debug_print_state(s)
|
||||||
|
# define tcp_debug_print_pcbs()
|
||||||
# define tcp_pcbs_sane() 1
|
# define tcp_pcbs_sane() 1
|
||||||
#endif /* TCP_DEBUG */
|
#endif /* TCP_DEBUG */
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user