📄 tcp.c
字号:
break; case SR_CANCEL_READ:assert (tcp_fd->tf_flags & TFF_READ_IP); tcp_fd->tf_flags &= ~TFF_READ_IP; if (tcp_conn->tc_readuser == tcp_fd) { tcp_conn->tc_readuser= 0; tcp_restart_fd_read (tcp_conn); } if (tcp_fd->tf_read_count) reply_thr_put (tcp_fd, tcp_fd->tf_read_count, FALSE); else reply_thr_put (tcp_fd, EINTR, FALSE); break; case SR_CANCEL_IOCTL:assert (tcp_fd->tf_flags & TFF_IOCTL_IP); tcp_fd->tf_flags &= ~TFF_IOCTL_IP; type= tcp_fd->tf_ioreq & IOCTYPE_MASK; switch (type) { case NWIOGTCPCONF & IOCTYPE_MASK: reply_thr_put (tcp_fd, EINTR, TRUE); break; case NWIOSTCPCONF & IOCTYPE_MASK: case NWIOTCPSHUTDOWN & IOCTYPE_MASK: case NWIOTCPATTACH & IOCTYPE_MASK: reply_thr_get (tcp_fd, EINTR, TRUE); break; case NWIOTCPCONN & IOCTYPE_MASK: case NWIOTCPLISTEN & IOCTYPE_MASK:assert (tcp_conn->tc_connuser == tcp_fd); tcp_conn->tc_connuser= 0; tcp_conn->tc_mainuser= 0; tcp_close_connection(tcp_conn, ENOCONN); reply_thr_get (tcp_fd, EINTR, TRUE); break; default: ip_warning(( "unknown ioctl inprogress: 0x%x", tcp_fd->tf_ioreq )); reply_thr_get (tcp_fd, EINTR, TRUE); break; } break; default: ip_panic(( "unknown cancel request" )); break; } return NW_OK;}/*tcp_connect*/PRIVATE int tcp_connect(tcp_fd)tcp_fd_t *tcp_fd;{ tcp_conn_t *tcp_conn; int state; if (!(tcp_fd->tf_flags & TFF_OPTSET)) {#if DEBUG { where(); }#endif tcp_reply_ioctl(tcp_fd, EBADMODE); return NW_OK; } if (tcp_fd->tf_flags & TFF_CONNECT) { tcp_reply_ioctl(tcp_fd, EISCONN); return NW_OK; } if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP)) != (NWTC_SET_RA|NWTC_SET_RP)) {#if DEBUG { where(); printf("tcp_fd_table[%d].tf_tcpconf.nwtc_flags= 0x%x\n", tcp_fd-tcp_fd_table, tcp_fd->tf_tcpconf.nwtc_flags); }#endif tcp_reply_ioctl(tcp_fd, EBADMODE); return NW_OK; }assert(!tcp_fd->tf_conn); tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport, tcp_fd->tf_port->tp_ipaddr, tcp_fd->tf_tcpconf.nwtc_remport, tcp_fd->tf_tcpconf.nwtc_remaddr); if (tcp_conn) { if (tcp_conn->tc_mainuser) { tcp_reply_ioctl(tcp_fd, EADDRINUSE); return NW_OK; } } else { tcp_conn= find_empty_conn(); if (!tcp_conn) { tcp_reply_ioctl(tcp_fd, EAGAIN); return NW_OK; } } tcp_fd->tf_conn= tcp_conn; return tcp_su4connect(tcp_fd);}/*tcp_su4connect*/PRIVATE int tcp_su4connect(tcp_fd)tcp_fd_t *tcp_fd;{ tcp_conn_t *tcp_conn; acc_t *tmp_acc; tcp_conn= tcp_fd->tf_conn; tcp_conn->tc_locport= tcp_fd->tf_tcpconf.nwtc_locport; tcp_conn->tc_locaddr= tcp_fd->tf_port->tp_ipaddr;assert (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RP);assert (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RA); tcp_conn->tc_remport= tcp_fd->tf_tcpconf.nwtc_remport; tcp_conn->tc_remaddr= tcp_fd->tf_tcpconf.nwtc_remaddr; tcp_conn->tc_mainuser= tcp_fd; tcp_setup_conn(tcp_conn); tcp_conn->tc_port= tcp_fd->tf_port; tcp_conn->tc_connuser= tcp_fd;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_connuser= 0x%x\n", tcp_conn- tcp_conn_table, tcp_conn->tc_connuser); }#endif tcp_conn->tc_orglisten= FALSE; tcp_conn->tc_state= TCS_SYN_SENT;#if DEBUG & 16 { where(); tcp_write_state(tcp_conn); }#endif tcp_restart_write (tcp_conn); if (tcp_conn->tc_connuser) return NW_SUSPEND; else return NW_OK;}PRIVATE void close_mainuser(tcp_conn, tcp_fd)tcp_conn_t *tcp_conn;tcp_fd_t *tcp_fd;{ int i; if (tcp_conn->tc_mainuser != tcp_fd) return; tcp_conn->tc_mainuser= 0; assert (tcp_conn->tc_writeuser != tcp_fd); assert (tcp_conn->tc_readuser != tcp_fd); assert (tcp_conn->tc_connuser != tcp_fd); for (i= 0, tcp_fd= tcp_fd_table; i<TCP_FD_NR; i++, tcp_fd++) { if (!(tcp_fd->tf_flags & TFF_INUSE)) continue; if (tcp_fd->tf_conn != tcp_conn) continue; tcp_conn->tc_mainuser= tcp_fd; return; }}PRIVATE int conn_right4fd(tcp_conn, tcp_fd)tcp_fd_t *tcp_fd;tcp_conn_t *tcp_conn;{ unsigned long flags; flags= tcp_fd->tf_tcpconf.nwtc_flags; if (tcp_fd->tf_tcpconf.nwtc_locport != tcp_conn->tc_locport) return FALSE; if ((flags & NWTC_SET_RA) && tcp_fd->tf_tcpconf.nwtc_remaddr != tcp_conn->tc_remaddr) return FALSE; if ((flags & NWTC_SET_RP) && tcp_fd->tf_tcpconf.nwtc_remport != tcp_conn->tc_remport) return FALSE; if (tcp_fd->tf_port != tcp_conn->tc_port) return FALSE; return TRUE;}PRIVATE int tcp_attache(tcp_fd)tcp_fd_t *tcp_fd;{ tcp_conn_t *tcp_conn; int state; if (!(tcp_fd->tf_flags & TFF_OPTSET)) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get(tcp_fd, EBADMODE, TRUE); return NW_OK; } if (tcp_fd->tf_flags & TFF_CONNECT) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get(tcp_fd, EISCONN, TRUE); return NW_OK; } if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP)) != (NWTC_SET_RA|NWTC_SET_RP)) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get(tcp_fd, EBADMODE, TRUE); return NW_OK; } tcp_conn= find_conn_entry(tcp_fd->tf_tcpconf.nwtc_locport, tcp_fd->tf_port->tp_ipaddr, tcp_fd->tf_tcpconf.nwtc_remport, tcp_fd->tf_tcpconf.nwtc_remaddr); if (!tcp_conn) {#if DEBUG { where(); printf("conn_entry not found\n"); }#endif tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get (tcp_fd, ENOCONN, TRUE); return NW_OK; } assert (tcp_conn->tc_flags & TCF_INUSE); state= tcp_conn->tc_state; if (state == TCS_CLOSED || state == TCS_LISTEN || state == TCS_SYN_SENT || state == TCS_SYN_RECEIVED) {#if DEBUG { where(); printf("conn_entry in wrong state: "); tcp_write_state(tcp_conn); printf("\n"); }#endif tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get (tcp_fd, ENOCONN, TRUE); return NW_OK; } tcp_fd->tf_conn= tcp_conn; tcp_fd->tf_flags |= TFF_CONNECTED; tcp_fd->tf_flags |= TFF_PUSH_DATA; /* XXX */ return NW_OK;}/*tcp_listen*/PRIVATE int tcp_listen(tcp_fd)tcp_fd_t *tcp_fd;{ tcp_conn_t *tcp_conn; int state;#if DEBUG & 256 { where(); printf("tcp_listen(&tcp_fd_table[%d]) called\n", tcp_fd- tcp_fd_table); }#endif if (!(tcp_fd->tf_flags & TFF_OPTSET)) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get(tcp_fd, EBADMODE, TRUE); return NW_OK; } if (tcp_fd->tf_flags & TFF_CONNECT) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get(tcp_fd, EISCONN, TRUE); return NW_OK; } tcp_conn= tcp_fd->tf_conn;assert(!tcp_conn); if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP)) == (NWTC_SET_RA|NWTC_SET_RP)) { tcp_conn= find_conn_entry( tcp_fd->tf_tcpconf.nwtc_locport, tcp_fd->tf_port->tp_ipaddr, tcp_fd->tf_tcpconf.nwtc_remport, tcp_fd->tf_tcpconf.nwtc_remaddr); if (tcp_conn) { if (tcp_conn->tc_mainuser) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get (tcp_fd, EADDRINUSE, TRUE); return NW_OK; } tcp_fd->tf_conn= tcp_conn; return tcp_su4listen(tcp_fd); } } tcp_conn= find_empty_conn(); if (!tcp_conn) { tcp_fd->tf_flags &= ~TFF_IOCTL_IP; reply_thr_get (tcp_fd, EAGAIN, TRUE); return NW_OK; } tcp_fd->tf_conn= tcp_conn;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_connuser= 0x%x\n", tcp_conn- tcp_conn_table, tcp_conn->tc_connuser); }#endif return tcp_su4listen(tcp_fd);}PRIVATE void tcp_buffree (priority, reqsize)int priority;size_t reqsize;{ int i; tcp_conn_t *tcp_conn; if (priority <TCP_PRI_FRAG2SEND) return;#if DEBUG & 256 { where(); printf("tcp_buffree called\n"); }#endif for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++, tcp_conn++) { if (!(tcp_conn->tc_flags & TCF_INUSE)) continue; if (!tcp_conn->tc_frag2send) continue; bf_afree(tcp_conn->tc_frag2send); tcp_conn->tc_frag2send= 0; if (bf_free_buffsize >= reqsize) return; } if (priority <TCP_PRI_CONNwoUSER) return; for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++, tcp_conn++) { if (!(tcp_conn->tc_flags & TCF_INUSE)) continue; if (tcp_conn->tc_mainuser) continue; if (tcp_conn->tc_state == TCS_CLOSED) continue;#if DEBUG { where(); printf("calling tcp_close_connection (out of memory)\n"); }#endif tcp_close_connection (tcp_conn, EOUTOFBUFS); if (bf_free_buffsize >= reqsize) return; } if (priority <TCP_PRI_CONN_INUSE) return; for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++, tcp_conn++) { if (!(tcp_conn->tc_flags & TCF_INUSE)) continue; if (tcp_conn->tc_state == TCS_CLOSED) continue;#if DEBUG { where(); printf("calling tcp_close_connection (out of memory)\n"); }#endif tcp_close_connection (tcp_conn, EOUTOFBUFS); if (bf_free_buffsize >= reqsize) return; }}PRIVATE void tcp_notreach(pack)acc_t *pack;{ acc_t *tcp_pack; ip_hdr_t *ip_hdr; tcp_hdr_t *tcp_hdr; tcp_conn_t *tcp_conn; int ip_hdr_size; int new_ttl; pack->acc_linkC++; pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE); ip_hdr= (ip_hdr_t *)ptr2acc_data(pack); ip_hdr_size= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2; tcp_pack= bf_cut(pack, ip_hdr_size, TCP_MIN_HDR_SIZE); tcp_pack= bf_packIffLess(tcp_pack, TCP_MIN_HDR_SIZE); tcp_hdr= (tcp_hdr_t *)ptr2acc_data(tcp_pack); tcp_conn= find_conn_entry( tcp_hdr->th_srcport, ip_hdr->ih_src, tcp_hdr->th_dstport, ip_hdr->ih_dst); if (tcp_conn) { new_ttl= tcp_conn->tc_ttl; if (new_ttl == IP_MAX_TTL) {#if DEBUG { where(); printf("calling tcp_close_connection\n"); }#endif tcp_close_connection(tcp_conn, EDSTNOTRCH); bf_afree(pack); bf_afree(tcp_pack); return; } new_ttl *= 2; if (new_ttl> IP_MAX_TTL) new_ttl= IP_MAX_TTL; tcp_conn->tc_ttl= new_ttl; tcp_conn->tc_no_retrans= 0; } else {#if DEBUG { where(); printf("got a EDSTNOTRCH for non existing connection\n"); }#endif } bf_afree(pack); bf_afree(tcp_pack);}/*tcp_setup_conn*/PRIVATE void tcp_setup_conn(tcp_conn)tcp_conn_t *tcp_conn;{assert(!tcp_conn->tc_readuser);assert(!tcp_conn->tc_writeuser);assert(!tcp_conn->tc_connuser); if (tcp_conn->tc_flags & TCF_INUSE) {assert (tcp_conn->tc_state == TCS_CLOSED || tcp_conn->tc_state == TCS_TIME_WAIT);assert (!tcp_conn->tc_send_data); if (tcp_conn->tc_senddis < get_time()) tcp_conn->tc_ISS= 0; } else { tcp_conn->tc_senddis= 0; tcp_conn->tc_ISS= 0; tcp_conn->tc_tos= TCP_DEF_TOS; tcp_conn->tc_ttl= TCP_DEF_TTL; tcp_conn->tc_rcv_wnd= TCP_MAX_WND_SIZE; tcp_conn->tc_urg_wnd= TCP_DEF_URG_WND; } if (!tcp_conn->tc_ISS) { tcp_conn->tc_ISS= (get_time()/HZ)*ISS_INC_FREQ; } tcp_conn->tc_SND_UNA= tcp_conn->tc_ISS; tcp_conn->tc_SND_TRM= tcp_conn->tc_ISS; tcp_conn->tc_SND_NXT= tcp_conn->tc_ISS+1; tcp_conn->tc_SND_UP= tcp_conn->tc_ISS; tcp_conn->tc_SND_PSH= tcp_conn->tc_ISS; tcp_conn->tc_SND_WL2= tcp_conn->tc_ISS; tcp_conn->tc_IRS= 0; tcp_conn->tc_SND_WL1= tcp_conn->tc_IRS; tcp_conn->tc_RCV_LO= tcp_conn->tc_IRS; tcp_conn->tc_RCV_NXT= tcp_conn->tc_IRS; tcp_conn->tc_RCV_HI= tcp_conn->tc_IRS; tcp_conn->tc_RCV_UP= tcp_conn->tc_IRS; tcp_conn->tc_rcvd_data= 0; tcp_conn->tc_rcv_queue= 0; tcp_conn->tc_send_data= 0; tcp_conn->tc_remipopt= 0; tcp_conn->tc_remtcpopt= 0; tcp_conn->tc_frag2send= 0; tcp_conn->tc_no_retrans= 0; tcp_conn->tc_max_no_retrans= TCP_DEF_MAX_NO_RETRANS; tcp_conn->tc_0wnd_to= 0; tcp_conn->tc_rtt= TCP_DEF_RTT; tcp_conn->tc_ett= 0; tcp_conn->tc_mss= TCP_DEF_MSS; tcp_conn->tc_error= NW_OK; tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + tcp_conn->tc_mss; tcp_conn->tc_snd_cthresh= TCP_MAX_WND_SIZE; tcp_conn->tc_snd_cinc= 0; tcp_conn->tc_snd_wnd= TCP_MAX_WND_SIZE; tcp_conn->tc_flags= TCF_INUSE;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -