Renamed tcp_output_set_header to tcp_output_alloc_header and included more code common to all callers

This commit is contained in:
goldsimon 2010-03-09 16:29:19 +00:00
parent ffbb582dde
commit 36d7f50d77

View File

@ -58,34 +58,38 @@
/* Forward declarations.*/ /* Forward declarations.*/
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
/** Create a tcphdr at p->payload, used for output functions other than the /** Allocate a pbuf and create a tcphdr at p->payload, used for output
* default tcp_output -> tcp_output_segment (e.g. tcp_send_empty_ack, etc.) * functions other than the default tcp_output -> tcp_output_segment
* (e.g. tcp_send_empty_ack, etc.)
* *
* @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr)
* @param p pbuf to send, p->payload will be the tcp_hdr
* @param optlen length of header-options * @param optlen length of header-options
* @param seqno_be seqno in network byte order (big-endian) * @param seqno_be seqno in network byte order (big-endian)
* @return pointer to the filled tcp_hdr * @return pbuf with p->payload being the tcp_hdr
*/ */
static struct tcp_hdr * static struct pbuf *
tcp_output_set_header(struct tcp_pcb *pcb, struct pbuf *p, u16_t optlen, tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen,
u32_t seqno_be /* already in network byte order */) u32_t seqno_be /* already in network byte order */)
{ {
struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; struct tcp_hdr *tcphdr;
tcphdr->src = htons(pcb->local_port); struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM);
tcphdr->dest = htons(pcb->remote_port); if (p != NULL) {
tcphdr->seqno = seqno_be; LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr",
tcphdr->ackno = htonl(pcb->rcv_nxt); (p->len >= TCP_HLEN + optlen));
TCPH_FLAGS_SET(tcphdr, TCP_ACK); tcphdr = (struct tcp_hdr *)p->payload;
tcphdr->wnd = htons(pcb->rcv_ann_wnd); tcphdr->src = htons(pcb->local_port);
tcphdr->urgp = 0; tcphdr->dest = htons(pcb->remote_port);
TCPH_HDRLEN_SET(tcphdr, (5 + optlen / 4)); tcphdr->seqno = seqno_be;
tcphdr->chksum = 0; tcphdr->ackno = htonl(pcb->rcv_nxt);
TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
tcphdr->wnd = htons(pcb->rcv_ann_wnd);
tcphdr->chksum = 0;
tcphdr->urgp = 0;
/* If we're sending a packet, update the announced right window edge */ /* If we're sending a packet, update the announced right window edge */
pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
}
return tcphdr; return p;
} }
/** /**
@ -711,18 +715,18 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
} }
#endif #endif
p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM);
p = tcp_output_alloc_header(pcb, optlen, htonl(pcb->snd_nxt));
if (p == NULL) { if (p == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
return ERR_BUF; return ERR_BUF;
} }
tcphdr = (struct tcp_hdr *)p->payload;
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
/* remove ACK flags from the PCB, as we send an empty ACK now */ /* remove ACK flags from the PCB, as we send an empty ACK now */
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt));
/* NB. MSS option is only sent on SYNs, so ignore it here */ /* NB. MSS option is only sent on SYNs, so ignore it here */
#if LWIP_TCP_TIMESTAMPS #if LWIP_TCP_TIMESTAMPS
pcb->ts_lastacksent = pcb->rcv_nxt; pcb->ts_lastacksent = pcb->rcv_nxt;
@ -1028,12 +1032,11 @@ tcp_rst(u32_t seqno, u32_t ackno,
tcphdr->dest = htons(remote_port); tcphdr->dest = htons(remote_port);
tcphdr->seqno = htonl(seqno); tcphdr->seqno = htonl(seqno);
tcphdr->ackno = htonl(ackno); tcphdr->ackno = htonl(ackno);
TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK); TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
tcphdr->wnd = htons(TCP_WND); tcphdr->wnd = htons(TCP_WND);
tcphdr->urgp = 0;
TCPH_HDRLEN_SET(tcphdr, 5);
tcphdr->chksum = 0; tcphdr->chksum = 0;
tcphdr->urgp = 0;
#if CHECKSUM_GEN_TCP #if CHECKSUM_GEN_TCP
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
IP_PROTO_TCP, p->tot_len); IP_PROTO_TCP, p->tot_len);
@ -1184,17 +1187,13 @@ tcp_keepalive(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n",
tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); tcp_ticks, pcb->tmr, pcb->keep_cnt_sent));
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); p = tcp_output_alloc_header(pcb, 0, htonl(pcb->snd_nxt - 1));
if(p == NULL) { if(p == NULL) {
LWIP_DEBUGF(TCP_DEBUG, LWIP_DEBUGF(TCP_DEBUG,
("tcp_keepalive: could not allocate memory for pbuf\n")); ("tcp_keepalive: could not allocate memory for pbuf\n"));
return; return;
} }
LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", tcphdr = (struct tcp_hdr *)p->payload;
(p->len >= sizeof(struct tcp_hdr)));
tcphdr = tcp_output_set_header(pcb, p, 0, htonl(pcb->snd_nxt - 1));
#if CHECKSUM_GEN_TCP #if CHECKSUM_GEN_TCP
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,
@ -1231,7 +1230,6 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
struct pbuf *p; struct pbuf *p;
struct tcp_hdr *tcphdr; struct tcp_hdr *tcphdr;
struct tcp_seg *seg; struct tcp_seg *seg;
u16_t len;
u8_t is_fin; u8_t is_fin;
LWIP_DEBUGF(TCP_DEBUG, LWIP_DEBUGF(TCP_DEBUG,
@ -1255,18 +1253,13 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
} }
is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
/* @todo: is this correct? p->len should not depend on the FIN flag! */
len = is_fin ? TCP_HLEN : TCP_HLEN + 1;
p = pbuf_alloc(PBUF_IP, len, PBUF_RAM); p = tcp_output_alloc_header(pcb, 0, seg->tcphdr->seqno);
if(p == NULL) { if(p == NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
return; return;
} }
LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", tcphdr = (struct tcp_hdr *)p->payload;
(p->len >= sizeof(struct tcp_hdr)));
tcphdr = tcp_output_set_header(pcb, p, 0, seg->tcphdr->seqno);
if (is_fin) { if (is_fin) {
/* FIN segment, no data */ /* FIN segment, no data */