⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpsock.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 5 页
字号:
 if (rbs > TCP_MAX_WINDOW_FIELD_VALUE) return(FNS_EINVAL); /* Can only do this at the very beginning of the life of a socket, before    any data has been (or could have been) sent or received. This is because    changing the receive buffer size could interfere with protocol operation,    e.g., shrinking the buffer after a window has been advertised    with the larger buffer in mind. */ if (svp->sv_state == CLOSED) {     svp->sv_rq_max = *((int *)optval);     return(FNS_ENOERR); } else {     return(FNS_EOPNOTSUPP); }} /* tcp_setopt_rcvbuf *//*************************************************************************************/static int tcp_get_maxseg_option(so_t *sop,int optname,char *optval){ tcpsv_t *svp; svp = sop->so_svp; if (!svp) return(FNS_ENOTCONN); *((int *)optval) = svp->sv_mss; return(FNS_ENOERR);} /* tcp_get_maxseg_option *//*************************************************************************************//* Application can set a send MSS smaller than would be arrived at via the MSS option   in an incoming SYN or the MTU of the connection. */static int tcp_set_maxseg_option(so_t *sop,int optname,char *optval){  tcpsv_t *svp; int mss; svp = sop->so_svp; if (!svp) return(FNS_ENOERR); /* maybe we should return an error here? */ /* Only allow this option to be set at the beginning of the life of a socket */ if (svp->sv_state != CLOSED) return(FNS_EOPNOTSUPP); /* screen out values larger than the largest that can be accomodated in an    IP packet (assuming maximum-sized IP and TCP headers) */ mss = (*((int *)optval)); if (mss > (65535 - IP_MHL - SIZEOF_TCPH_T - TCP_MAX_SEG_OPTSIZE))  return(FNS_EINVAL); tcp_set_send_mss (svp,  (u16) mss,TCP_MSS_SOURCE_SOCKOPT ); return(FNS_ENOERR); } /* tcp_set_maxseg_option *//*************************************************************************************/static int tcp_set_rcvmss_option(so_t *sop,int optname,char *optval){ tcpsv_t *svp; int rcvmss; svp = sop->so_svp; if (!svp) return(FNS_ENOERR); /* maybe we should return an error here? */ /* Only allow this option to be set at the beginning of the life of a socket */ if (svp->sv_state != CLOSED) return(FNS_EOPNOTSUPP); /* screen out values larger than the largest that can be accomodated in an    IP packet */ rcvmss = (*((int *)optval)); if (rcvmss > (65535 - IP_MHL - SIZEOF_TCPH_T))  return(FNS_EINVAL); svp->sv_rcv_mss = rcvmss; return(FNS_ENOERR);} /* tcp_set_rcvmss_option *//* Functions to set or get a flag in sv_flags2 which indicates the setting of a binary   socket option *//*************************************************************************************/static int tcp_getopt_bitflag2(so_t *sop,int optname,char *optval){ tcpsv_t *svp; u16 which_bitflag; svp = sop->so_svp; if (!svp) return(FNS_ENOTCONN); switch (optname) {#ifdef TCP_WND_SCALE     case TCP_WINDOW_SCALE: which_bitflag = SV_WSCALE_PERMITTED; break;#endif#ifdef TCP_TIMESTAMPS     case TCP_PROVIDE_TIMESTAMPS: which_bitflag = SV_PROVIDE_TIMESTAMPS; break;#endif#ifdef TCP_PAWS     case TCP_ENABLE_PAWS: which_bitflag = SV_PAWS_ENABLED; break;#endif#ifdef TCP_RTTM     case TCP_RTT_ALGORITHM: which_bitflag = SV_RTTM_RFC_1323; break;#endif#ifdef TCP_SELACK_ENHANCEMENTS     case TCP_PERMIT_SACKS: which_bitflag = SV_PERMIT_IN_SACKS; break;     case TCP_SEND_SACKS:   which_bitflag = SV_OUT_SACKS_ALLOWED; break;#endif#ifdef TCP_SS_CA_FRETR_FREC      case TCP_FAST_RETR_RECOV: which_bitflag = SV_FAST_RETR_RECOV; break;     case TCP_SLOW_START_CA:   which_bitflag = SV_SLOW_START_CA; break;#endif     case TCP_NODELAY:         which_bitflag = SV_NAGLE_DISABLED; break;     default: return(FNS_EOPNOTSUPP); } /* switch */ *((int *)optval) = ( (svp->sv_flags2 & which_bitflag) ? 1 : 0 ); return(FNS_ENOERR);	 	  } /* tcp_getopt_bitflag2 *//*************************************************************************************/static int tcp_setopt_bitflag2(so_t *sop,int optname,char *optval){ tcpsv_t *svp; u16 which_bitflag;  svp = sop->so_svp; if (!svp) return(FNS_ENOERR); /* maybe we should return an error here? */ /* Only valid to set this option at the beginning of the life of a socket, because    this is something that is negotiated during connection establishment */ if (svp->sv_state != CLOSED) return(FNS_EOPNOTSUPP);  switch (optname) {#ifdef TCP_WND_SCALE     case TCP_WINDOW_SCALE: which_bitflag = SV_WSCALE_PERMITTED; break;#endif#ifdef TCP_TIMESTAMPS     case TCP_PROVIDE_TIMESTAMPS: which_bitflag = SV_PROVIDE_TIMESTAMPS; break;#endif#ifdef TCP_PAWS     case TCP_ENABLE_PAWS: which_bitflag = SV_PAWS_ENABLED; break;#endif#ifdef TCP_RTTM     case TCP_RTT_ALGORITHM: which_bitflag = SV_RTTM_RFC_1323; break;#endif     case TCP_USE_PEER_MSS_OPTION: which_bitflag = SV_USE_PEER_MSS_OPTION; break;#ifdef TCP_SELACK_ENHANCEMENTS     case TCP_PERMIT_SACKS: which_bitflag = SV_PERMIT_IN_SACKS; break;     case TCP_SEND_SACKS:   which_bitflag = SV_OUT_SACKS_ALLOWED; break;#endif#ifdef TCP_SS_CA_FRETR_FREC      case TCP_FAST_RETR_RECOV: which_bitflag = SV_FAST_RETR_RECOV; break;     case TCP_SLOW_START_CA:   which_bitflag = SV_SLOW_START_CA; break;#endif     case TCP_NODELAY:         which_bitflag = SV_NAGLE_DISABLED; break;     default: return(FNS_EOPNOTSUPP); } /* switch */ if (*((int *)optval)) svp->sv_flags2 |= which_bitflag; else                  svp->sv_flags2 &= ~which_bitflag; return(FNS_ENOERR);	  } /* tcp_setopt_bitflag2 */#ifdef TCP_TRANSACTION_TCP/*************************************************************************************/static int tcp_setopt_trans(so_t *sop,int optname,char *optval){ tcpsv_t *svp; svp = sop->so_svp; if (!svp) return(FNS_ENOERR); /* maybe we should return an error here? */ /* Only valid to set this option at the beginning of the life of a socket */ if (svp->sv_state != CLOSED) return(FNS_EOPNOTSUPP); if (*((int *)optval)) svp->sv_t_tcp_flags |= SV_TRANSACTION; else                  svp->sv_t_tcp_flags &= ~SV_TRANSACTION; return(FNS_ENOERR);} /* tcp_setopt_trans */#endif /* TCP_TRANSACTION_TCP  *//* Functions to set or get an integer parameter in the state vector via socket option *//*************************************************************************************/static int tcp_getopt_int(so_t *sop,int optname,char *optval){ tcpsv_t *svp; u32 which_int; svp = sop->so_svp; if (!svp) return(FNS_ENOTCONN); switch (optname) {     case TCP_REX_MAX: which_int = svp->sv_maxretrim; break;     case TCP_REX_MIN: which_int = svp->sv_minretrim; break;     case TCP_REX_INIT: which_int = svp->sv_initretrim; break;     case TCP_ACKDELAYTIME:  which_int = svp->sv_ackdelay; break;     case TCP_ACKNSEG:    which_int =  svp->sv_ackEveryN; break;     default: return(FNS_EOPNOTSUPP); } /* switch */ *((int *)optval) = which_int; return(FNS_ENOERR);	 	  } /* tcp_getopt_int *//*************************************************************************************/static int tcp_setopt_retr(so_t *sop,int optname,char *optval){ tcpsv_t *svp; u32 *initrex; u32 *minrex; u32 *maxrex; u32 *which_field;  svp = sop->so_svp; if (!svp) return(FNS_ENOERR); /* maybe we should return an error here? */  initrex = &(svp->sv_initretrim); minrex  = &(svp->sv_minretrim); maxrex  = &(svp->sv_maxretrim); switch (optname) {     case TCP_REX_MAX:  which_field = maxrex; maxrex = ((u32 *) optval); break;     case TCP_REX_MIN:  which_field = minrex; minrex = ((u32 *) optval); break;     case TCP_REX_INIT: which_field = initrex; initrex = ((u32 *) optval); break;     default: return(FNS_EOPNOTSUPP); } /* switch */ /* Make sure the new value stands in proper relationship to the other related    parameters */ if ( (*minrex > *initrex) || (*initrex > *maxrex) ) return(FNS_EINVAL); *which_field = (*((u32 *) optval)); return(FNS_ENOERR);	  } /* tcp_setopt_retr *//*************************************************************************************/static int tcp_setopt_ackdly(so_t *sop,int optname,char *optval){ tcpsv_t *svp; i32 oval = *((i32 *) optval);  svp = sop->so_svp; if (!svp) return(FNS_ENOERR); /* maybe we should return an error here? */   switch (optname) {     case TCP_ACKNSEG:    if (oval < 1) oval = 1;		                  svp->sv_ackEveryN = oval; 						  break;     case TCP_ACKDELAYTIME:  		                  if (oval < 0) return(FNS_EINVAL);						  if (oval < MS_PER_TICK) oval = MS_PER_TICK;						  svp->sv_ackdelay = oval;						  break;     default: return(FNS_EOPNOTSUPP); } /* switch */ return(FNS_ENOERR);	  } /* tcp_setopt_ackdly *//*************************************************************************************//* TCP set options */export  int     tcp_setopt (fast so_t * sop, int level, int optname , u8 *optval, 							 int optlen){    int     err = FNS_ENOERR;    switch ((unsigned)level) {      case SOL_SOCKET:          /* if the option has no processing at the TCP layer, pass it on down		     to the IP layer, otherwise do the TCP layer processing before passing			 it on down to the IPlayer */		  if (find_sockopt_entry(optname, &(tcp_sol_sockopts[0])) != 0) {             /* process using info in the tcp socket-level option table above */             err = process_set_sockopt(sop,optname,(u8 *) optval,optlen,	   		                          &(tcp_sol_sockopts[0]));             if (err != FNS_ENOERR) return(err); 		  }          /* intentional fall thru to IPPROTO_IP case */      case IPPROTO_IP:        if ((err = ip_setopt(sop, level, optname, optval, optlen)) != 0)            return err;        tcp_glomopt(sop);        return (FNS_ENOERR);      case IPPROTO_TCP:                    /* process using info in the tcp-level socket option table above */          return(process_set_sockopt(sop,optname,(u8 *) optval,optlen,			                          &(tcp_sockopts[0])));      default:        return FNS_EPROTOTYPE;    } }/*********************************************************************//* 9.4.6.3.41 Send Fin. [155..6] */#ifndef TCP_TRANSACTION_TCPpflocal void    tcp_sfin (fast tcpsv_t * svp)#elseexport void    tcp_sfin (fast tcpsv_t * svp, boolean xmit_now)#endif /* TCP_TRANSACTION_TCP */{    use_critical;#ifdef MSD_DEBUG    so_t * sop;#endif    trace0(tcp_trace, "tcp_sfin:\n");    assert(svp->sv_refcnt != 0, "tcp_sfin: sv not bound\n");    critical;    trace0(tcp_tsfin, "tcp_sfin: marking send FIN flag\n");    svp->sv_flags |= SV_TFINFLG;    /* mark FIN to be sent */    M32U(svp->sv_snxt, +=, 1);#ifdef TCP_TRANSACTION_TCP	/* See: RFC 1644 state diagram Figure 8A, Figure 8B, and Figure 9 */	if (  ( (!(svp->sv_t_tcp_flags & SV_TRANSACTION)) &&		    ( svp->sv_state != SYN_SENT) )		                 ||	      ( (svp->sv_t_tcp_flags & SV_TRANSACTION) &&		  ( (svp->sv_state == CLOSE_WAIT) || (svp->sv_state == ESTAB) ) ) ) {       #endif /* TCP_TRANSACTION_TCP */     set_state("tcp_sfin", svp, (svp->sv_state == CLOSE_WAIT) ? LAST_ACK : FIN1_WAIT);#ifdef TCP_TRANSACTION_TCP	}#endif /* TCP_TRANSACTION_TCP */    normal;#ifdef MSD_DEBUG    if ( msd_debug  &&  ((sop = svp->sv_sop) != (so_t *)0) ) os_printf("tcp_sfin: [%d]\n", sop->so_index);#endif#ifdef TCP_TRANSACTION_TCP	if (xmit_now)#endif /* TCP_TRANSACTION_TCP */    tcp_sqxmit(svp); /* send new "data" */} export  int     tcp_shutdown (fast so_t * sop, int direction){    fast    tcpsv_t * svp;    int     err;    use_critical;    trace0(tcp_trace, "tcp_shutdown:\n");    critical;    if ((svp = sop->so_svp) == (tcpsv_t *)0) {        debug0(tcp_debug, "tcp_shutdown: no state vector\n");        normal;        err = FNS_ENOTCONN;        goto out;    }    sv_bind(svp, tcp_shutdown, true);    err = 0;    norm

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -