📄 tcp_send.c
字号:
DIFBLOCK(0x10, (tcp_conn->tc_fd == 0), printf("conn[%d] timeout in abondoned connection\n", tcp_conn-tcp_conn_table)); /* At this point, we have do a retransmission, or send a zero window * probe, which is almost the same. */ DBLOCK(0x20, printf("tcp_send_timeout: conn[%d] una= %lu, rtt= %ldms\n", tcp_conn-tcp_conn_table, (unsigned long)tcp_conn->tc_SND_UNA, rtt*1000/HZ)); /* Update threshold sequence number for retransmission calculation. */ if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_rt_threshold)) tcp_conn->tc_rt_threshold= tcp_conn->tc_SND_TRM; tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA; if (tcp_conn->tc_flags & TCF_PMTU && curr_time > stt+TCP_PMTU_BLACKHOLE) { /* We can't tell the difference between a PMTU blackhole * and a broken link. Assume a PMTU blackhole, and switch * off PMTU discovery. */ DBLOCK(1, printf( "tcp[%d]: PMTU blackhole (or broken link) on route to ", tcp_conn-tcp_conn_table); writeIpAddr(tcp_conn->tc_remaddr); printf(", max mtu = %u\n", tcp_conn->tc_max_mtu);); tcp_conn->tc_flags &= ~TCF_PMTU; tcp_conn->tc_mtutim= curr_time; if (tcp_conn->tc_max_mtu > IP_DEF_MTU) tcp_conn->tc_mtu= IP_DEF_MTU; } mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE; mss2= 2*mss; if (tcp_conn->tc_snd_cwnd == tcp_conn->tc_SND_UNA) tcp_conn->tc_snd_cwnd++; if (tcp_Gmod4G(tcp_conn->tc_snd_cwnd, tcp_conn->tc_SND_UNA + mss2)) { tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + mss2; if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd)) tcp_conn->tc_SND_TRM= tcp_conn->tc_snd_cwnd; tcp_conn->tc_snd_cthresh /= 2; if (tcp_conn->tc_snd_cthresh < mss2) tcp_conn->tc_snd_cthresh= mss2; } if (curr_time-stt > tcp_conn->tc_rt_dead) { tcp_close_connection(tcp_conn, ETIMEDOUT); return; } timeout= (curr_time-stt) >> 3; if (timeout < rtt) timeout= rtt; timeout += curr_time; DBLOCK(0x20, printf( "tcp_send_timeout: conn[%d] setting timer to %ld ms (+%ld ms)\n", tcp_conn-tcp_conn_table, timeout*1000/HZ, (timeout-curr_time)*1000/HZ)); clck_timer(&tcp_conn->tc_transmit_timer, timeout, tcp_send_timeout, tcp_conn-tcp_conn_table);#if 0 if (tcp_conn->tc_rt_seq == 0) { printf("tcp_send_timeout: conn[%d]: setting tc_rt_time\n", tcp_conn-tcp_conn_table); tcp_conn->tc_rt_time= curr_time-rtt; tcp_conn->tc_rt_seq= tcp_conn->tc_SND_UNA; }#endif if (tcp_conn->tc_state == TCS_SYN_SENT || (curr_time-stt >= tcp_conn->tc_ttl*HZ)) { new_ttl= tcp_conn->tc_ttl+1; if (new_ttl> IP_MAX_TTL) new_ttl= IP_MAX_TTL; tcp_conn->tc_ttl= new_ttl; } tcp_conn_write(tcp_conn, 0);}PUBLIC void tcp_fd_write(tcp_conn)tcp_conn_t *tcp_conn;{ tcp_fd_t *tcp_fd; int urg, nourg, push; u32_t max_seq; size_t max_trans, write_count; acc_t *data, *send_data; assert(tcp_conn->tc_busy); tcp_fd= tcp_conn->tc_fd; if ((tcp_fd->tf_flags & TFF_IOCTL_IP) && !(tcp_fd->tf_flags & TFF_WRITE_IP)) { if (tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN) return; DBLOCK(0x10, printf("NWIOTCPSHUTDOWN\n")); if (tcp_conn->tc_state == TCS_CLOSED) { tcp_reply_ioctl (tcp_fd, tcp_conn->tc_error); return; } if (!(tcp_conn->tc_flags & TCF_FIN_SENT)) { DBLOCK(0x10, printf("calling tcp_shutdown\n")); tcp_shutdown (tcp_conn); } else { if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT) { tcp_reply_ioctl (tcp_fd, NW_OK); DBLOCK(0x10, printf("shutdown completed\n")); } else { DBLOCK(0x10, printf("shutdown still inprogress\n")); } } return; } assert (tcp_fd->tf_flags & TFF_WRITE_IP); if (tcp_conn->tc_state == TCS_CLOSED) { if (tcp_fd->tf_write_offset) { tcp_reply_write(tcp_fd, tcp_fd->tf_write_offset); } else tcp_reply_write(tcp_fd, tcp_conn->tc_error); return; } urg= (tcp_fd->tf_flags & TFF_WR_URG); push= (tcp_fd->tf_flags & TFF_PUSH_DATA); max_seq= tcp_conn->tc_SND_UNA + TCP_MAX_SND_WND_SIZE; max_trans= max_seq - tcp_conn->tc_SND_NXT; if (tcp_fd->tf_write_count <= max_trans) write_count= tcp_fd->tf_write_count; else write_count= max_trans; if (write_count) { if (tcp_conn->tc_flags & TCF_BSD_URG) { if (tcp_Gmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_UNA)) { nourg= tcp_LEmod4G(tcp_conn->tc_SND_UP, tcp_conn->tc_SND_UNA); if ((urg && nourg) || (!urg && !nourg)) { DBLOCK(0x20, printf("not sending\n")); return; } } } data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, tcp_fd->tf_write_offset, write_count, FALSE); if (!data) { if (tcp_fd->tf_write_offset) { tcp_reply_write(tcp_fd, tcp_fd->tf_write_offset); } else tcp_reply_write(tcp_fd, EFAULT); return; } tcp_fd->tf_write_offset += write_count; tcp_fd->tf_write_count -= write_count; send_data= tcp_conn->tc_send_data; tcp_conn->tc_send_data= 0; send_data= bf_append(send_data, data); tcp_conn->tc_send_data= send_data; tcp_conn->tc_SND_NXT += write_count; if (urg) { if (tcp_conn->tc_flags & TCF_BSD_URG) tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT; else tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT-1; } if (push && !tcp_fd->tf_write_count) tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT; } if (!tcp_fd->tf_write_count) { tcp_reply_write(tcp_fd, tcp_fd->tf_write_offset); }}PUBLIC unsigned tcp_sel_write(tcp_conn)tcp_conn_t *tcp_conn;{ tcp_fd_t *tcp_fd; int urg, nourg; u32_t max_seq; size_t max_trans; tcp_fd= tcp_conn->tc_fd; if (tcp_conn->tc_state == TCS_CLOSED) return 1; urg= (tcp_fd->tf_flags & TFF_WR_URG); max_seq= tcp_conn->tc_SND_UNA + TCP_MAX_SND_WND_SIZE; max_trans= max_seq - tcp_conn->tc_SND_NXT; if (max_trans) { if (tcp_conn->tc_flags & TCF_BSD_URG) { if (tcp_Gmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_UNA)) { nourg= tcp_LEmod4G(tcp_conn->tc_SND_UP, tcp_conn->tc_SND_UNA); if ((urg && nourg) || (!urg && !nourg)) { DBLOCK(0x20, printf("not sending\n")); return 0; } } } return 1; } return 0;}PUBLIC voidtcp_rsel_write(tcp_conn)tcp_conn_t *tcp_conn;{ tcp_fd_t *tcp_fd; if (tcp_sel_write(tcp_conn) == 0) return; tcp_fd= tcp_conn->tc_fd; tcp_fd->tf_flags &= ~TFF_SEL_WRITE; if (tcp_fd->tf_select_res) tcp_fd->tf_select_res(tcp_fd->tf_srfd, SR_SELECT_WRITE); else printf("tcp_rsel_write: no select_res\n");}/*tcp_shutdown*/PUBLIC void tcp_shutdown(tcp_conn)tcp_conn_t *tcp_conn;{ switch (tcp_conn->tc_state) { case TCS_CLOSED: case TCS_LISTEN: case TCS_SYN_SENT: case TCS_SYN_RECEIVED: tcp_close_connection(tcp_conn, ENOTCONN); return; } if (tcp_conn->tc_flags & TCF_FIN_SENT) return; tcp_conn->tc_flags |= TCF_FIN_SENT; tcp_conn->tc_flags &= ~TCF_NO_PUSH; tcp_conn->tc_SND_NXT++; tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT; assert (tcp_check_conn(tcp_conn) || (tcp_print_conn(tcp_conn), printf("\n"), 0)); tcp_conn_write(tcp_conn, 1); /* Start the timer */ tcp_set_send_timer(tcp_conn);}PUBLIC void tcp_set_send_timer(tcp_conn)tcp_conn_t *tcp_conn;{ clock_t curr_time; clock_t rtt; assert(tcp_conn->tc_state != TCS_CLOSED); assert(tcp_conn->tc_state != TCS_LISTEN); curr_time= get_time(); rtt= tcp_conn->tc_rtt; DBLOCK(0x20, printf( "tcp_set_send_timer: conn[%d] setting timer to %ld ms (+%ld ms)\n", tcp_conn-tcp_conn_table, (curr_time+rtt)*1000/HZ, rtt*1000/HZ)); /* Start the timer */ clck_timer(&tcp_conn->tc_transmit_timer, curr_time+rtt, tcp_send_timeout, tcp_conn-tcp_conn_table); tcp_conn->tc_stt= curr_time;}/*tcp_close_connection*/PUBLIC void tcp_close_connection(tcp_conn, error)tcp_conn_t *tcp_conn;int error;{ int i; tcp_port_t *tcp_port; tcp_fd_t *tcp_fd; tcp_conn_t *tc; assert (tcp_check_conn(tcp_conn) || (tcp_print_conn(tcp_conn), printf("\n"), 0)); assert (tcp_conn->tc_flags & TCF_INUSE); tcp_conn->tc_error= error; tcp_port= tcp_conn->tc_port; tcp_fd= tcp_conn->tc_fd; if (tcp_conn->tc_state == TCS_CLOSED) return; tcp_conn->tc_state= TCS_CLOSED; DBLOCK(0x10, tcp_print_state(tcp_conn); printf("\n")); if (tcp_fd && (tcp_fd->tf_flags & TFF_LISTENQ)) { for (i= 0; i<TFL_LISTEN_MAX; i++) { if (tcp_fd->tf_listenq[i] == tcp_conn) break; } assert(i < TFL_LISTEN_MAX); tcp_fd->tf_listenq[i]= NULL; assert(tcp_conn->tc_connInprogress); tcp_conn->tc_connInprogress= 0; tcp_conn->tc_fd= NULL; tcp_fd= NULL; } else if (tcp_fd) { tcp_conn->tc_busy++; assert(tcp_fd->tf_conn == tcp_conn); if (tcp_fd->tf_flags & TFF_READ_IP) tcp_fd_read (tcp_conn, 1); assert (!(tcp_fd->tf_flags & TFF_READ_IP)); if (tcp_fd->tf_flags & TFF_SEL_READ) tcp_rsel_read (tcp_conn); if (tcp_fd->tf_flags & TFF_WRITE_IP) { tcp_fd_write(tcp_conn); tcp_conn_write(tcp_conn, 1); } assert (!(tcp_fd->tf_flags & TFF_WRITE_IP)); if (tcp_fd->tf_flags & TFF_IOCTL_IP) { tcp_fd_write(tcp_conn); tcp_conn_write(tcp_conn, 1); } if (tcp_fd->tf_flags & TFF_IOCTL_IP) assert(tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN); if (tcp_fd->tf_flags & TFF_SEL_WRITE) tcp_rsel_write(tcp_conn); if (tcp_conn->tc_connInprogress) tcp_restart_connect(tcp_conn); assert (!tcp_conn->tc_connInprogress); assert (!(tcp_fd->tf_flags & TFF_IOCTL_IP) || (printf("req= 0x%lx\n", (unsigned long)tcp_fd->tf_ioreq), 0)); tcp_conn->tc_busy--; } if (tcp_conn->tc_rcvd_data) { bf_afree(tcp_conn->tc_rcvd_data); tcp_conn->tc_rcvd_data= NULL; } tcp_conn->tc_flags &= ~TCF_FIN_RECV; tcp_conn->tc_RCV_LO= tcp_conn->tc_RCV_NXT; if (tcp_conn->tc_adv_data) { bf_afree(tcp_conn->tc_adv_data); tcp_conn->tc_adv_data= NULL; } if (tcp_conn->tc_send_data) { bf_afree(tcp_conn->tc_send_data); tcp_conn->tc_send_data= NULL; tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA; } tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA; if (tcp_conn->tc_remipopt) { bf_afree(tcp_conn->tc_remipopt); tcp_conn->tc_remipopt= NULL; } if (tcp_conn->tc_tcpopt) { bf_afree(tcp_conn->tc_tcpopt); tcp_conn->tc_tcpopt= NULL; } if (tcp_conn->tc_frag2send) { bf_afree(tcp_conn->tc_frag2send); tcp_conn->tc_frag2send= NULL; } if (tcp_conn->tc_flags & TCF_MORE2WRITE) { for (tc= tcp_port->tp_snd_head; tc; tc= tc->tc_send_link) { if (tc->tc_send_link == tcp_conn) break; } if (tc == NULL) { assert(tcp_port->tp_snd_head == tcp_conn); tcp_port->tp_snd_head= tcp_conn->tc_send_link; } else { tc->tc_send_link= tcp_conn->tc_send_link; if (tc->tc_send_link == NULL) tcp_port->tp_snd_tail= tc; } tcp_conn->tc_flags &= ~TCF_MORE2WRITE; } clck_untimer (&tcp_conn->tc_transmit_timer); tcp_conn->tc_transmit_seq= 0; /* clear all flags but TCF_INUSE */ tcp_conn->tc_flags &= TCF_INUSE; assert (tcp_check_conn(tcp_conn));}/* * $PchId: tcp_send.c,v 1.32 2005/06/28 14:21:52 philip Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -