109 |
tcp_tmr(void) |
tcp_tmr(void) |
110 |
{ |
{ |
111 |
++tcp_timer; |
++tcp_timer; |
112 |
if(tcp_timer == 10) { |
if (tcp_timer == 10) { |
113 |
tcp_timer = 0; |
tcp_timer = 0; |
114 |
} |
} |
115 |
|
|
116 |
if(tcp_timer & 1) { |
if (tcp_timer & 1) { |
117 |
/* Call tcp_fasttmr() every 200 ms, i.e., every other timer |
/* Call tcp_fasttmr() every 200 ms, i.e., every other timer |
118 |
tcp_tmr() is called. */ |
tcp_tmr() is called. */ |
119 |
tcp_fasttmr(); |
tcp_fasttmr(); |
120 |
} |
} |
121 |
if(tcp_timer == 0 || tcp_timer == 5) { |
if (tcp_timer == 0 || tcp_timer == 5) { |
122 |
/* Call tcp_slowtmr() every 500 ms, i.e., every fifth timer |
/* Call tcp_slowtmr() every 500 ms, i.e., every fifth timer |
123 |
tcp_tmr() is called. */ |
tcp_tmr() is called. */ |
124 |
tcp_slowtmr(); |
tcp_slowtmr(); |
142 |
tcp_debug_print_state(pcb->state); |
tcp_debug_print_state(pcb->state); |
143 |
DEBUGF(TCP_DEBUG, ("\n")); |
DEBUGF(TCP_DEBUG, ("\n")); |
144 |
#endif /* TCP_DEBUG */ |
#endif /* TCP_DEBUG */ |
145 |
switch(pcb->state) { |
switch (pcb->state) { |
146 |
case LISTEN: |
case LISTEN: |
147 |
err = ERR_OK; |
err = ERR_OK; |
148 |
tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs, pcb); |
tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs, pcb); |
157 |
break; |
break; |
158 |
case SYN_RCVD: |
case SYN_RCVD: |
159 |
err = tcp_send_ctrl(pcb, TCP_FIN); |
err = tcp_send_ctrl(pcb, TCP_FIN); |
160 |
if(err == ERR_OK) { |
if (err == ERR_OK) { |
161 |
pcb->state = FIN_WAIT_1; |
pcb->state = FIN_WAIT_1; |
162 |
} |
} |
163 |
break; |
break; |
164 |
case ESTABLISHED: |
case ESTABLISHED: |
165 |
err = tcp_send_ctrl(pcb, TCP_FIN); |
err = tcp_send_ctrl(pcb, TCP_FIN); |
166 |
if(err == ERR_OK) { |
if (err == ERR_OK) { |
167 |
pcb->state = FIN_WAIT_1; |
pcb->state = FIN_WAIT_1; |
168 |
} |
} |
169 |
break; |
break; |
170 |
case CLOSE_WAIT: |
case CLOSE_WAIT: |
171 |
err = tcp_send_ctrl(pcb, TCP_FIN); |
err = tcp_send_ctrl(pcb, TCP_FIN); |
172 |
if(err == ERR_OK) { |
if (err == ERR_OK) { |
173 |
pcb->state = LAST_ACK; |
pcb->state = LAST_ACK; |
174 |
} |
} |
175 |
break; |
break; |
180 |
break; |
break; |
181 |
} |
} |
182 |
|
|
183 |
if(pcb != NULL && err == ERR_OK) { |
if (pcb != NULL && err == ERR_OK) { |
184 |
err = tcp_output(pcb); |
err = tcp_output(pcb); |
185 |
} |
} |
186 |
return err; |
return err; |
210 |
/* Figure out on which TCP PCB list we are, and remove us. If we |
/* Figure out on which TCP PCB list we are, and remove us. If we |
211 |
are in an active state, call the receive function associated with |
are in an active state, call the receive function associated with |
212 |
the PCB with a NULL argument, and send an RST to the remote end. */ |
the PCB with a NULL argument, and send an RST to the remote end. */ |
213 |
if(pcb->state == TIME_WAIT) { |
if (pcb->state == TIME_WAIT) { |
214 |
tcp_pcb_remove(&tcp_tw_pcbs, pcb); |
tcp_pcb_remove(&tcp_tw_pcbs, pcb); |
215 |
memp_free(MEMP_TCP_PCB, pcb); |
memp_free(MEMP_TCP_PCB, pcb); |
216 |
} else { |
} else { |
225 |
#endif /* LWIP_CALLBACK_API */ |
#endif /* LWIP_CALLBACK_API */ |
226 |
errf_arg = pcb->callback_arg; |
errf_arg = pcb->callback_arg; |
227 |
tcp_pcb_remove(&tcp_active_pcbs, pcb); |
tcp_pcb_remove(&tcp_active_pcbs, pcb); |
228 |
if(pcb->unacked != NULL) { |
if (pcb->unacked != NULL) { |
229 |
tcp_segs_free(pcb->unacked); |
tcp_segs_free(pcb->unacked); |
230 |
} |
} |
231 |
if(pcb->unsent != NULL) { |
if (pcb->unsent != NULL) { |
232 |
tcp_segs_free(pcb->unsent); |
tcp_segs_free(pcb->unsent); |
233 |
} |
} |
234 |
#if TCP_QUEUE_OOSEQ |
#if TCP_QUEUE_OOSEQ |
235 |
if(pcb->ooseq != NULL) { |
if (pcb->ooseq != NULL) { |
236 |
tcp_segs_free(pcb->ooseq); |
tcp_segs_free(pcb->ooseq); |
237 |
} |
} |
238 |
#endif /* TCP_QUEUE_OOSEQ */ |
#endif /* TCP_QUEUE_OOSEQ */ |
257 |
{ |
{ |
258 |
struct tcp_pcb *cpcb; |
struct tcp_pcb *cpcb; |
259 |
|
|
260 |
if(port == 0) { |
if (port == 0) { |
261 |
port = tcp_new_port(); |
port = tcp_new_port(); |
262 |
} |
} |
263 |
|
|
264 |
/* Check if the address already is in use. */ |
/* Check if the address already is in use. */ |
265 |
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs; |
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs; |
266 |
cpcb != NULL; cpcb = cpcb->next) { |
cpcb != NULL; cpcb = cpcb->next) { |
267 |
if(cpcb->local_port == port) { |
if (cpcb->local_port == port) { |
268 |
if(ip_addr_isany(&(cpcb->local_ip)) || |
if (ip_addr_isany(&(cpcb->local_ip)) || |
269 |
ip_addr_isany(ipaddr) || |
ip_addr_isany(ipaddr) || |
270 |
ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { |
ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { |
271 |
return ERR_USE; |
return ERR_USE; |
274 |
} |
} |
275 |
for(cpcb = tcp_active_pcbs; |
for(cpcb = tcp_active_pcbs; |
276 |
cpcb != NULL; cpcb = cpcb->next) { |
cpcb != NULL; cpcb = cpcb->next) { |
277 |
if(cpcb->local_port == port) { |
if (cpcb->local_port == port) { |
278 |
if(ip_addr_isany(&(cpcb->local_ip)) || |
if (ip_addr_isany(&(cpcb->local_ip)) || |
279 |
ip_addr_isany(ipaddr) || |
ip_addr_isany(ipaddr) || |
280 |
ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { |
ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { |
281 |
return ERR_USE; |
return ERR_USE; |
282 |
} |
} |
283 |
} |
} |
284 |
} |
} |
285 |
if(!ip_addr_isany(ipaddr)) { |
if (!ip_addr_isany(ipaddr)) { |
286 |
pcb->local_ip = *ipaddr; |
pcb->local_ip = *ipaddr; |
287 |
} |
} |
288 |
pcb->local_port = port; |
pcb->local_port = port; |
313 |
struct tcp_pcb_listen *lpcb; |
struct tcp_pcb_listen *lpcb; |
314 |
|
|
315 |
/* already listening? */ |
/* already listening? */ |
316 |
if(pcb->state == LISTEN) { |
if (pcb->state == LISTEN) { |
317 |
return pcb; |
return pcb; |
318 |
} |
} |
319 |
lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN); |
lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN); |
320 |
if(lpcb == NULL) { |
if (lpcb == NULL) { |
321 |
return NULL; |
return NULL; |
322 |
} |
} |
323 |
lpcb->callback_arg = pcb->callback_arg; |
lpcb->callback_arg = pcb->callback_arg; |
345 |
tcp_recved(struct tcp_pcb *pcb, u16_t len) |
tcp_recved(struct tcp_pcb *pcb, u16_t len) |
346 |
{ |
{ |
347 |
pcb->rcv_wnd += len; |
pcb->rcv_wnd += len; |
348 |
if(pcb->rcv_wnd > TCP_WND) { |
if (pcb->rcv_wnd > TCP_WND) { |
349 |
pcb->rcv_wnd = TCP_WND; |
pcb->rcv_wnd = TCP_WND; |
350 |
} |
} |
351 |
if(!(pcb->flags & TF_ACK_DELAY) && |
if (!(pcb->flags & TF_ACK_DELAY) && |
352 |
!(pcb->flags & TF_ACK_NOW)) { |
!(pcb->flags & TF_ACK_NOW)) { |
353 |
tcp_ack(pcb); |
tcp_ack(pcb); |
354 |
} |
} |
374 |
static u16_t port = TCP_LOCAL_PORT_RANGE_START; |
static u16_t port = TCP_LOCAL_PORT_RANGE_START; |
375 |
|
|
376 |
again: |
again: |
377 |
if(++port > TCP_LOCAL_PORT_RANGE_END) { |
if (++port > TCP_LOCAL_PORT_RANGE_END) { |
378 |
port = TCP_LOCAL_PORT_RANGE_START; |
port = TCP_LOCAL_PORT_RANGE_START; |
379 |
} |
} |
380 |
|
|
381 |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
382 |
if(pcb->local_port == port) { |
if (pcb->local_port == port) { |
383 |
goto again; |
goto again; |
384 |
} |
} |
385 |
} |
} |
386 |
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { |
387 |
if(pcb->local_port == port) { |
if (pcb->local_port == port) { |
388 |
goto again; |
goto again; |
389 |
} |
} |
390 |
} |
} |
391 |
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) { |
392 |
if(pcb->local_port == port) { |
if (pcb->local_port == port) { |
393 |
goto again; |
goto again; |
394 |
} |
} |
395 |
} |
} |
413 |
u32_t iss; |
u32_t iss; |
414 |
|
|
415 |
DEBUGF(TCP_DEBUG, ("tcp_connect to port %u\n", port)); |
DEBUGF(TCP_DEBUG, ("tcp_connect to port %u\n", port)); |
416 |
if(ipaddr != NULL) { |
if (ipaddr != NULL) { |
417 |
pcb->remote_ip = *ipaddr; |
pcb->remote_ip = *ipaddr; |
418 |
} else { |
} else { |
419 |
return ERR_VAL; |
return ERR_VAL; |
420 |
} |
} |
421 |
pcb->remote_port = port; |
pcb->remote_port = port; |
422 |
if(pcb->local_port == 0) { |
if (pcb->local_port == 0) { |
423 |
pcb->local_port = tcp_new_port(); |
pcb->local_port = tcp_new_port(); |
424 |
} |
} |
425 |
iss = tcp_next_iss(); |
iss = tcp_next_iss(); |
445 |
(pcb->mss & 255)); |
(pcb->mss & 255)); |
446 |
|
|
447 |
ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4); |
ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4); |
448 |
if(ret == ERR_OK) { |
if (ret == ERR_OK) { |
449 |
tcp_output(pcb); |
tcp_output(pcb); |
450 |
} |
} |
451 |
return ret; |
return ret; |
475 |
prev = NULL; |
prev = NULL; |
476 |
pcb = tcp_active_pcbs; |
pcb = tcp_active_pcbs; |
477 |
if (pcb == NULL) DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); |
if (pcb == NULL) DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); |
478 |
while(pcb != NULL) { |
while (pcb != NULL) { |
479 |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); |
480 |
LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); |
LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); |
481 |
LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); |
LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); |
483 |
|
|
484 |
pcb_remove = 0; |
pcb_remove = 0; |
485 |
|
|
486 |
if(pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { |
if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { |
487 |
++pcb_remove; |
++pcb_remove; |
488 |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); |
489 |
} |
} |
490 |
else if(pcb->nrtx == TCP_MAXRTX) { |
else if (pcb->nrtx == TCP_MAXRTX) { |
491 |
++pcb_remove; |
++pcb_remove; |
492 |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); |
493 |
} else { |
} else { |
494 |
++pcb->rtime; |
++pcb->rtime; |
495 |
if(pcb->unacked != NULL && pcb->rtime >= pcb->rto) { |
if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { |
496 |
|
|
497 |
/* Time for a retransmission. */ |
/* Time for a retransmission. */ |
498 |
DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %u pcb->rto %u\n", |
DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %u pcb->rto %u\n", |
500 |
|
|
501 |
/* Double retransmission time-out unless we are trying to |
/* Double retransmission time-out unless we are trying to |
502 |
connect to somebody (i.e., we are in SYN_SENT). */ |
connect to somebody (i.e., we are in SYN_SENT). */ |
503 |
if(pcb->state != SYN_SENT) { |
if (pcb->state != SYN_SENT) { |
504 |
pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; |
pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; |
505 |
} |
} |
506 |
|
|
509 |
/* Reduce congestion window and ssthresh. */ |
/* Reduce congestion window and ssthresh. */ |
510 |
eff_wnd = MIN(pcb->cwnd, pcb->snd_wnd); |
eff_wnd = MIN(pcb->cwnd, pcb->snd_wnd); |
511 |
pcb->ssthresh = eff_wnd >> 1; |
pcb->ssthresh = eff_wnd >> 1; |
512 |
if(pcb->ssthresh < pcb->mss) { |
if (pcb->ssthresh < pcb->mss) { |
513 |
pcb->ssthresh = pcb->mss * 2; |
pcb->ssthresh = pcb->mss * 2; |
514 |
} |
} |
515 |
pcb->cwnd = pcb->mss; |
pcb->cwnd = pcb->mss; |
520 |
} |
} |
521 |
|
|
522 |
/* Check if this PCB has stayed too long in FIN-WAIT-2 */ |
/* Check if this PCB has stayed too long in FIN-WAIT-2 */ |
523 |
if(pcb->state == FIN_WAIT_2) { |
if (pcb->state == FIN_WAIT_2) { |
524 |
if((u32_t)(tcp_ticks - pcb->tmr) > |
if ((u32_t)(tcp_ticks - pcb->tmr) > |
525 |
TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { |
TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { |
526 |
++pcb_remove; |
++pcb_remove; |
527 |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); |
532 |
inactive for too long, will drop the data (it will eventually |
inactive for too long, will drop the data (it will eventually |
533 |
be retransmitted). */ |
be retransmitted). */ |
534 |
#if TCP_QUEUE_OOSEQ |
#if TCP_QUEUE_OOSEQ |
535 |
if(pcb->ooseq != NULL && |
if (pcb->ooseq != NULL && |
536 |
(u32_t)tcp_ticks - pcb->tmr >= |
(u32_t)tcp_ticks - pcb->tmr >= |
537 |
pcb->rto * TCP_OOSEQ_TIMEOUT) { |
pcb->rto * TCP_OOSEQ_TIMEOUT) { |
538 |
tcp_segs_free(pcb->ooseq); |
tcp_segs_free(pcb->ooseq); |
542 |
#endif /* TCP_QUEUE_OOSEQ */ |
#endif /* TCP_QUEUE_OOSEQ */ |
543 |
|
|
544 |
/* Check if this PCB has stayed too long in SYN-RCVD */ |
/* Check if this PCB has stayed too long in SYN-RCVD */ |
545 |
if(pcb->state == SYN_RCVD) { |
if (pcb->state == SYN_RCVD) { |
546 |
if((u32_t)(tcp_ticks - pcb->tmr) > |
if ((u32_t)(tcp_ticks - pcb->tmr) > |
547 |
TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { |
TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { |
548 |
++pcb_remove; |
++pcb_remove; |
549 |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); |
552 |
|
|
553 |
|
|
554 |
/* If the PCB should be removed, do it. */ |
/* If the PCB should be removed, do it. */ |
555 |
if(pcb_remove) { |
if (pcb_remove) { |
556 |
tcp_pcb_purge(pcb); |
tcp_pcb_purge(pcb); |
557 |
/* Remove PCB from tcp_active_pcbs list. */ |
/* Remove PCB from tcp_active_pcbs list. */ |
558 |
if(prev != NULL) { |
if (prev != NULL) { |
559 |
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); |
560 |
prev->next = pcb->next; |
prev->next = pcb->next; |
561 |
} else { |
} else { |
573 |
|
|
574 |
/* We check if we should poll the connection. */ |
/* We check if we should poll the connection. */ |
575 |
++pcb->polltmr; |
++pcb->polltmr; |
576 |
if(pcb->polltmr >= pcb->pollinterval) { |
if (pcb->polltmr >= pcb->pollinterval) { |
577 |
pcb->polltmr = 0; |
pcb->polltmr = 0; |
578 |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); |
DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); |
579 |
TCP_EVENT_POLL(pcb, err); |
TCP_EVENT_POLL(pcb, err); |
580 |
if(err == ERR_OK) { |
if (err == ERR_OK) { |
581 |
tcp_output(pcb); |
tcp_output(pcb); |
582 |
} |
} |
583 |
} |
} |
591 |
/* Steps through all of the TIME-WAIT PCBs. */ |
/* Steps through all of the TIME-WAIT PCBs. */ |
592 |
prev = NULL; |
prev = NULL; |
593 |
pcb = tcp_tw_pcbs; |
pcb = tcp_tw_pcbs; |
594 |
while(pcb != NULL) { |
while (pcb != NULL) { |
595 |
LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); |
LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); |
596 |
pcb_remove = 0; |
pcb_remove = 0; |
597 |
|
|
598 |
/* Check if this PCB has stayed long enough in TIME-WAIT */ |
/* Check if this PCB has stayed long enough in TIME-WAIT */ |
599 |
if((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { |
if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { |
600 |
++pcb_remove; |
++pcb_remove; |
601 |
} |
} |
602 |
|
|
603 |
|
|
604 |
|
|
605 |
/* If the PCB should be removed, do it. */ |
/* If the PCB should be removed, do it. */ |
606 |
if(pcb_remove) { |
if (pcb_remove) { |
607 |
tcp_pcb_purge(pcb); |
tcp_pcb_purge(pcb); |
608 |
/* Remove PCB from tcp_tw_pcbs list. */ |
/* Remove PCB from tcp_tw_pcbs list. */ |
609 |
if(prev != NULL) { |
if (prev != NULL) { |
610 |
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); |
611 |
prev->next = pcb->next; |
prev->next = pcb->next; |
612 |
} else { |
} else { |
637 |
|
|
638 |
/* send delayed ACKs */ |
/* send delayed ACKs */ |
639 |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
640 |
if(pcb->flags & TF_ACK_DELAY) { |
if (pcb->flags & TF_ACK_DELAY) { |
641 |
DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); |
DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); |
642 |
tcp_ack_now(pcb); |
tcp_ack_now(pcb); |
643 |
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); |
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); |
658 |
u8_t count = 0; |
u8_t count = 0; |
659 |
struct tcp_seg *next; |
struct tcp_seg *next; |
660 |
again: |
again: |
661 |
if(seg != NULL) { |
if (seg != NULL) { |
662 |
next = seg->next; |
next = seg->next; |
663 |
count += tcp_seg_free(seg); |
count += tcp_seg_free(seg); |
664 |
seg = next; |
seg = next; |
679 |
{ |
{ |
680 |
u8_t count = 0; |
u8_t count = 0; |
681 |
|
|
682 |
if(seg != NULL) { |
if (seg != NULL) { |
683 |
if(seg->p == NULL) { |
if (seg->p == NULL) { |
684 |
memp_free(MEMP_TCP_SEG, seg); |
memp_free(MEMP_TCP_SEG, seg); |
685 |
} else { |
} else { |
686 |
count = pbuf_free(seg->p); |
count = pbuf_free(seg->p); |
719 |
struct tcp_seg *cseg; |
struct tcp_seg *cseg; |
720 |
|
|
721 |
cseg = memp_malloc(MEMP_TCP_SEG); |
cseg = memp_malloc(MEMP_TCP_SEG); |
722 |
if(cseg == NULL) { |
if (cseg == NULL) { |
723 |
return NULL; |
return NULL; |
724 |
} |
} |
725 |
memcpy((char *)cseg, (const char *)seg, sizeof(struct tcp_seg)); |
memcpy((char *)cseg, (const char *)seg, sizeof(struct tcp_seg)); |
732 |
tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) |
tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) |
733 |
{ |
{ |
734 |
arg = arg; |
arg = arg; |
735 |
if(p != NULL) { |
if (p != NULL) { |
736 |
pbuf_free(p); |
pbuf_free(p); |
737 |
} else if(err == ERR_OK) { |
} else if (err == ERR_OK) { |
738 |
return tcp_close(pcb); |
return tcp_close(pcb); |
739 |
} |
} |
740 |
return ERR_OK; |
return ERR_OK; |
756 |
inactivity = 0; |
inactivity = 0; |
757 |
inactive = NULL; |
inactive = NULL; |
758 |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
759 |
if(pcb->prio <= prio && |
if (pcb->prio <= prio && |
760 |
pcb->prio <= mprio && |
pcb->prio <= mprio && |
761 |
(u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { |
(u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { |
762 |
inactivity = tcp_ticks - pcb->tmr; |
inactivity = tcp_ticks - pcb->tmr; |
764 |
mprio = pcb->prio; |
mprio = pcb->prio; |
765 |
} |
} |
766 |
} |
} |
767 |
if(inactive != NULL) { |
if (inactive != NULL) { |
768 |
DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n", |
DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n", |
769 |
(void *)inactive, inactivity)); |
(void *)inactive, inactivity)); |
770 |
tcp_abort(inactive); |
tcp_abort(inactive); |
781 |
inactivity = 0; |
inactivity = 0; |
782 |
inactive = NULL; |
inactive = NULL; |
783 |
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { |
784 |
if((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { |
if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { |
785 |
inactivity = tcp_ticks - pcb->tmr; |
inactivity = tcp_ticks - pcb->tmr; |
786 |
inactive = pcb; |
inactive = pcb; |
787 |
} |
} |
788 |
} |
} |
789 |
if(inactive != NULL) { |
if (inactive != NULL) { |
790 |
DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n", |
DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n", |
791 |
(void *)inactive, inactivity)); |
(void *)inactive, inactivity)); |
792 |
tcp_abort(inactive); |
tcp_abort(inactive); |
802 |
u32_t iss; |
u32_t iss; |
803 |
|
|
804 |
pcb = memp_malloc(MEMP_TCP_PCB); |
pcb = memp_malloc(MEMP_TCP_PCB); |
805 |
if(pcb == NULL) { |
if (pcb == NULL) { |
806 |
/* Try killing oldest connection in TIME-WAIT. */ |
/* Try killing oldest connection in TIME-WAIT. */ |
807 |
DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); |
DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); |
808 |
tcp_kill_timewait(); |
tcp_kill_timewait(); |
809 |
pcb = memp_malloc(MEMP_TCP_PCB); |
pcb = memp_malloc(MEMP_TCP_PCB); |
810 |
if(pcb == NULL) { |
if (pcb == NULL) { |
811 |
tcp_kill_prio(prio); |
tcp_kill_prio(prio); |
812 |
pcb = memp_malloc(MEMP_TCP_PCB); |
pcb = memp_malloc(MEMP_TCP_PCB); |
813 |
} |
} |
814 |
} |
} |
815 |
if(pcb != NULL) { |
if (pcb != NULL) { |
816 |
memset(pcb, 0, sizeof(struct tcp_pcb)); |
memset(pcb, 0, sizeof(struct tcp_pcb)); |
817 |
pcb->prio = TCP_PRIO_NORMAL; |
pcb->prio = TCP_PRIO_NORMAL; |
818 |
pcb->snd_buf = TCP_SND_BUF; |
pcb->snd_buf = TCP_SND_BUF; |
966 |
void |
void |
967 |
tcp_pcb_purge(struct tcp_pcb *pcb) |
tcp_pcb_purge(struct tcp_pcb *pcb) |
968 |
{ |
{ |
969 |
if(pcb->state != CLOSED && |
if (pcb->state != CLOSED && |
970 |
pcb->state != TIME_WAIT && |
pcb->state != TIME_WAIT && |
971 |
pcb->state != LISTEN) { |
pcb->state != LISTEN) { |
972 |
|
|
973 |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); |
974 |
|
|
975 |
#if TCP_DEBUG |
#if TCP_DEBUG |
976 |
if(pcb->unsent != NULL) { |
if (pcb->unsent != NULL) { |
977 |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); |
978 |
} |
} |
979 |
if(pcb->unacked != NULL) { |
if (pcb->unacked != NULL) { |
980 |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); |
981 |
} |
} |
982 |
#if TCP_QUEUE_OOSEQ /* LW */ |
#if TCP_QUEUE_OOSEQ /* LW */ |
983 |
if(pcb->ooseq != NULL) { |
if (pcb->ooseq != NULL) { |
984 |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); |
DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); |
985 |
} |
} |
986 |
#endif |
#endif |
1013 |
tcp_pcb_purge(pcb); |
tcp_pcb_purge(pcb); |
1014 |
|
|
1015 |
/* if there is an outstanding delayed ACKs, send it */ |
/* if there is an outstanding delayed ACKs, send it */ |
1016 |
if(pcb->state != TIME_WAIT && |
if (pcb->state != TIME_WAIT && |
1017 |
pcb->state != LISTEN && |
pcb->state != LISTEN && |
1018 |
pcb->flags & TF_ACK_DELAY) { |
pcb->flags & TF_ACK_DELAY) { |
1019 |
pcb->flags |= TF_ACK_NOW; |
pcb->flags |= TF_ACK_NOW; |
1076 |
tcp_debug_print_state(enum tcp_state s) |
tcp_debug_print_state(enum tcp_state s) |
1077 |
{ |
{ |
1078 |
DEBUGF(TCP_DEBUG, ("State: ")); |
DEBUGF(TCP_DEBUG, ("State: ")); |
1079 |
switch(s) { |
switch (s) { |
1080 |
case CLOSED: |
case CLOSED: |
1081 |
DEBUGF(TCP_DEBUG, ("CLOSED\n")); |
DEBUGF(TCP_DEBUG, ("CLOSED\n")); |
1082 |
break; |
break; |
1116 |
void |
void |
1117 |
tcp_debug_print_flags(u8_t flags) |
tcp_debug_print_flags(u8_t flags) |
1118 |
{ |
{ |
1119 |
if(flags & TCP_FIN) { |
if (flags & TCP_FIN) { |
1120 |
DEBUGF(TCP_DEBUG, ("FIN ")); |
DEBUGF(TCP_DEBUG, ("FIN ")); |
1121 |
} |
} |
1122 |
if(flags & TCP_SYN) { |
if (flags & TCP_SYN) { |
1123 |
DEBUGF(TCP_DEBUG, ("SYN ")); |
DEBUGF(TCP_DEBUG, ("SYN ")); |
1124 |
} |
} |
1125 |
if(flags & TCP_RST) { |
if (flags & TCP_RST) { |
1126 |
DEBUGF(TCP_DEBUG, ("RST ")); |
DEBUGF(TCP_DEBUG, ("RST ")); |
1127 |
} |
} |
1128 |
if(flags & TCP_PSH) { |
if (flags & TCP_PSH) { |
1129 |
DEBUGF(TCP_DEBUG, ("PSH ")); |
DEBUGF(TCP_DEBUG, ("PSH ")); |
1130 |
} |
} |
1131 |
if(flags & TCP_ACK) { |
if (flags & TCP_ACK) { |
1132 |
DEBUGF(TCP_DEBUG, ("ACK ")); |
DEBUGF(TCP_DEBUG, ("ACK ")); |
1133 |
} |
} |
1134 |
if(flags & TCP_URG) { |
if (flags & TCP_URG) { |
1135 |
DEBUGF(TCP_DEBUG, ("URG ")); |
DEBUGF(TCP_DEBUG, ("URG ")); |
1136 |
} |
} |
1137 |
} |
} |