📄 inet.c
字号:
// read only if (ss_tst_bit(_T_BIT_TCP_INFO, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.tcp.info);#endif if (ss_tst_bit(_T_BIT_TCP_QUICKACK, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.tcp.quickack); break;#if defined HAVE_OPENSS7_SCTP case T_INET_SCTP: if (ss_tst_bit(_T_BIT_SCTP_NODELAY, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.nodelay); if (ss_tst_bit(_T_BIT_SCTP_MAXSEG, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.maxseg); if (ss_tst_bit(_T_BIT_SCTP_CORK, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.cork); if (ss_tst_bit(_T_BIT_SCTP_PPI, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.ppi); if (ss_tst_bit(_T_BIT_SCTP_SID, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.sid); if (ss_tst_bit(_T_BIT_SCTP_SSN, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.ssn); if (ss_tst_bit(_T_BIT_SCTP_TSN, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.tsn); if (ss_tst_bit(_T_BIT_SCTP_RECVOPT, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.recvopt); if (ss_tst_bit(_T_BIT_SCTP_COOKIE_LIFE, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.cookie_life); if (ss_tst_bit(_T_BIT_SCTP_SACK_DELAY, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.sack_delay); if (ss_tst_bit(_T_BIT_SCTP_PATH_MAX_RETRANS, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.path_max_retrans); if (ss_tst_bit(_T_BIT_SCTP_ASSOC_MAX_RETRANS, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.assoc_max_retrans); if (ss_tst_bit(_T_BIT_SCTP_MAX_INIT_RETRIES, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.max_init_retries); if (ss_tst_bit(_T_BIT_SCTP_HEARTBEAT_ITVL, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.heartbeat_itvl); if (ss_tst_bit(_T_BIT_SCTP_RTO_INITIAL, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.rto_initial); if (ss_tst_bit(_T_BIT_SCTP_RTO_MIN, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.rto_min); if (ss_tst_bit(_T_BIT_SCTP_RTO_MAX, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.rto_max); { /* These two have end-to-end significance for connection indications and connection responses */ // if (ss_tst_bit(_T_BIT_SCTP_OSTREAMS, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.ostreams); // if (ss_tst_bit(_T_BIT_SCTP_ISTREAMS, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.istreams); } if (ss_tst_bit(_T_BIT_SCTP_COOKIE_INC, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.cookie_inc); if (ss_tst_bit(_T_BIT_SCTP_THROTTLE_ITVL, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.throttle_itvl); if (ss_tst_bit(_T_BIT_SCTP_MAC_TYPE, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.mac_type); if (ss_tst_bit(_T_BIT_SCTP_HB, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.hb); if (ss_tst_bit(_T_BIT_SCTP_RTO, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.rto); if (ss_tst_bit(_T_BIT_SCTP_STATUS, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.status); if (ss_tst_bit(_T_BIT_SCTP_DEBUG, ss->options.flags)) size += _T_SPACE_SIZEOF(ss->options.sctp.debug); break;#endif /* defined HAVE_OPENSS7_SCTP */ } } return (size);}/* * Build connection confirmation options. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * These are options with end-to-end significance plus any options without * end-to-end significance that were requested for negotiation in the * connection request. For a connection indication, this is only options * with end-to-end significance. For this to work with connection * indications, all options request flags must be set to zero. The retrn * value is the resulting size of the options buffer, or a negative error * number on software fault. * * The t_connect() or t_rcvconnect() functions return the values of all * options with end-to-end significance that were received with the * connection response and the negotiated values of those options without * end-to-end significance that had been specified on input. However, * options specified on input with t_connect() call that are not supported or * refer to an unknown option level are discarded and not returned on output. * * The status field of each option returned with t_connect() or * t_rcvconnect() indicates if the proposed value (T_SUCCESS) or a degraded * value (T_PARTSUCCESS) has been negotiated. The status field of received * ancillary information (for example, T_IP options) that is not subject to * negotiation is always set to T_SUCCESS. */STATIC intss_build_conn_opts(ss_t * ss, unsigned char *op, size_t olen){ struct t_opthdr *oh; struct sock *sk; if (op == NULL || olen == 0) return (0); if (!ss || !ss->sock || !(sk = ss->sock->sk)) goto eproto; oh = _T_OPT_FIRSTHDR_OFS(op, olen, 0); if (ss_tst_bit(_T_BIT_XTI_DEBUG, ss->options.flags)) { oh->level = XTI_GENERIC; oh->name = XTI_DEBUG; oh->len = _T_LENGTH_SIZEOF(ss->options.xti.debug); oh->status = T_SUCCESS; bcopy(ss->options.xti.debug, T_OPT_DATA(oh), sizeof(ss->options.xti.debug)); oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_XTI_LINGER, ss->options.flags)) { oh->level = XTI_GENERIC; oh->name = XTI_LINGER; oh->len = _T_LENGTH_SIZEOF(ss->options.xti.linger); oh->status = T_SUCCESS; if ((sk->linger == 1) != (ss->options.xti.linger.l_onoff == T_YES)) { ss->options.xti.linger.l_onoff = sk->linger ? T_YES : T_NO; } if (ss->options.xti.linger.l_onoff == T_YES) { if (ss->options.xti.linger.l_linger != sk->lingertime / HZ) { if (ss->options.xti.linger.l_linger != T_UNSPEC && ss->options.xti.linger.l_linger < sk->lingertime / HZ) oh->status = T_PARTSUCCESS; ss->options.xti.linger.l_linger = sk->lingertime / HZ; } } else ss->options.xti.linger.l_linger = T_UNSPEC; *((struct t_linger *) T_OPT_DATA(oh)) = ss->options.xti.linger; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_XTI_RCVBUF, ss->options.flags)) { oh->level = XTI_GENERIC; oh->name = XTI_RCVBUF; oh->len = _T_LENGTH_SIZEOF(ss->options.xti.rcvbuf); oh->status = T_SUCCESS; if (ss->options.xti.rcvbuf != sk->rcvbuf / 2) { if (ss->options.xti.rcvbuf != T_UNSPEC && ss->options.xti.rcvbuf < sk->rcvbuf / 2) oh->status = T_PARTSUCCESS; ss->options.xti.rcvbuf = sk->rcvbuf / 2; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.xti.rcvbuf; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_XTI_RCVLOWAT, ss->options.flags)) { oh->level = XTI_GENERIC; oh->name = XTI_RCVLOWAT; oh->len = _T_LENGTH_SIZEOF(ss->options.xti.rcvlowat); oh->status = T_SUCCESS; if (ss->options.xti.rcvlowat != sk->rcvlowat) { if (ss->options.xti.rcvlowat != T_UNSPEC && ss->options.xti.rcvlowat < sk->rcvlowat) oh->status = T_PARTSUCCESS; ss->options.xti.rcvlowat = sk->rcvlowat; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.xti.rcvlowat; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_XTI_SNDBUF, ss->options.flags)) { oh->level = XTI_GENERIC; oh->name = XTI_SNDBUF; oh->len = _T_LENGTH_SIZEOF(ss->options.xti.sndbuf); oh->status = T_SUCCESS; if (ss->options.xti.sndbuf != sk->sndbuf / 2) { if (ss->options.xti.sndbuf != T_UNSPEC && ss->options.xti.sndbuf < sk->sndbuf / 2) oh->status = T_PARTSUCCESS; ss->options.xti.sndbuf = sk->sndbuf / 2; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.xti.sndbuf; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_XTI_SNDLOWAT, ss->options.flags)) { oh->level = XTI_GENERIC; oh->name = XTI_SNDLOWAT; oh->len = _T_LENGTH_SIZEOF(ss->options.xti.sndlowat); oh->status = T_SUCCESS; if (ss->options.xti.sndlowat != 1) { if (ss->options.xti.sndlowat != T_UNSPEC && ss->options.xti.sndlowat < 1) oh->status = T_PARTSUCCESS; ss->options.xti.sndlowat = 1; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss_defaults.xti.sndlowat; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss->p.prot.family == PF_INET) { struct inet_opt *np = &sk->protinfo.af_inet; // if (ss_tst_bit(_T_BIT_IP_OPTIONS, ss->options.flags)) oh->level = T_INET_IP; oh->name = T_IP_OPTIONS; oh->len = _T_LENGTH_SIZEOF(ss->options.ip.options); oh->status = T_SUCCESS; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); // if (ss_tst_bit(_T_BIT_IP_TOS, ss->options.flags)) oh->level = T_INET_IP; oh->name = T_IP_TOS; oh->len = _T_LENGTH_SIZEOF(ss->options.ip.tos); oh->status = T_SUCCESS; if (ss->options.ip.tos != np->tos) { if (ss->options.ip.tos > np->tos) oh->status = T_PARTSUCCESS; ss->options.ip.tos = np->tos; } *((unsigned char *) T_OPT_DATA(oh)) = ss->options.ip.tos; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); if (ss_tst_bit(_T_BIT_IP_TTL, ss->options.flags)) { oh->level = T_INET_IP; oh->name = T_IP_TTL; oh->len = _T_LENGTH_SIZEOF(ss->options.ip.ttl); oh->status = T_SUCCESS; if (ss->options.ip.ttl != np->ttl) { if (ss->options.ip.ttl > np->ttl) oh->status = T_PARTSUCCESS; ss->options.ip.ttl = np->ttl; } *((unsigned char *) T_OPT_DATA(oh)) = ss->options.ip.ttl; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_IP_REUSEADDR, ss->options.flags)) { oh->level = T_INET_IP; oh->name = T_IP_REUSEADDR; oh->len = _T_LENGTH_SIZEOF(unsigned int); oh->status = T_SUCCESS; if ((ss->options.ip.reuseaddr == T_NO) != (sk->reuse == 0)) { oh->status = T_PARTSUCCESS; ss->options.ip.reuseaddr = sk->reuse ? T_YES : T_NO; } *((unsigned int *) T_OPT_DATA(oh)) = ss->options.ip.reuseaddr; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_IP_DONTROUTE, ss->options.flags)) { oh->level = T_INET_IP; oh->name = T_IP_DONTROUTE; oh->len = _T_LENGTH_SIZEOF(unsigned int); oh->status = T_SUCCESS; if ((ss->options.ip.dontroute == T_NO) != (sk->localroute == 0)) { oh->status = T_PARTSUCCESS; ss->options.ip.dontroute = sk->localroute ? T_YES : T_NO; } *((unsigned int *) T_OPT_DATA(oh)) = ss->options.ip.dontroute; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_IP_BROADCAST, ss->options.flags)) { oh->level = T_INET_IP; oh->name = T_IP_BROADCAST; oh->len = _T_LENGTH_SIZEOF(unsigned int); oh->status = T_SUCCESS; if ((ss->options.ip.broadcast == T_NO) != (sk->broadcast == 0)) { oh->status = T_PARTSUCCESS; ss->options.ip.broadcast = sk->broadcast ? T_YES : T_NO; } *((unsigned int *) T_OPT_DATA(oh)) = ss->options.ip.broadcast; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_IP_ADDR, ss->options.flags)) { oh->level = T_INET_IP; oh->name = T_IP_ADDR; oh->len = _T_LENGTH_SIZEOF(uint32_t); oh->status = T_SUCCESS; *((uint32_t *) T_OPT_DATA(oh)) = ss->options.ip.addr; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } switch (ss->p.prot.protocol) { case T_INET_TCP: { struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; if (ss_tst_bit(_T_BIT_TCP_NODELAY, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_NODELAY; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if ((ss->options.tcp.nodelay == T_NO) != (tp->nonagle == 0)) { oh->status = T_PARTSUCCESS; ss->options.tcp.nodelay = tp->nonagle ? T_YES : T_NO; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.nodelay; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_MAXSEG, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_MAXSEG; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if (ss->options.tcp.maxseg != tp->user_mss) { if (ss->options.tcp.maxseg > tp->user_mss) oh->status = T_PARTSUCCESS; ss->options.tcp.maxseg = tp->user_mss; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.maxseg; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_KEEPALIVE, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_KEEPALIVE; oh->len = _T_LENGTH_SIZEOF(struct t_kpalive); oh->status = T_SUCCESS; if ((ss->options.tcp.keepalive.kp_onoff != T_NO) != (sk->keepopen != 0)) { ss->options.tcp.keepalive.kp_onoff = sk->keepopen ? T_YES : T_NO; } if (ss->options.tcp.keepalive.kp_onoff == T_YES) { if (ss->options.tcp.keepalive.kp_timeout != tp->keepalive_time / 60 / HZ) { if (ss->options.tcp.keepalive.kp_timeout != T_UNSPEC && ss->options.tcp.keepalive.kp_timeout > tp->keepalive_time / 60 / HZ) oh->status = T_PARTSUCCESS; ss->options.tcp.keepalive.kp_timeout = tp->keepalive_time / 60 / HZ; } } else ss->options.tcp.keepalive.kp_timeout = T_UNSPEC; *((struct t_kpalive *) T_OPT_DATA(oh)) = ss->options.tcp.keepalive; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_CORK, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_CORK; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if ((ss->options.tcp.cork == T_YES) != (tp->nonagle == 2)) { oh->status = T_FAILURE; ss->options.tcp.cork = (tp->nonagle == 2) ? T_YES : T_NO; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.cork; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_KEEPIDLE, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_KEEPIDLE; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if (ss->options.tcp.keepidle == T_UNSPEC) ss->options.tcp.keepidle = tp->keepalive_time / HZ; else if (ss->options.tcp.keepidle != tp->keepalive_time / HZ) { oh->status = T_PARTSUCCESS; ss->options.tcp.keepidle = tp->keepalive_time / HZ; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.keepidle; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_KEEPINTVL, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_KEEPINTVL; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if (ss->options.tcp.keepitvl == T_UNSPEC) ss->options.tcp.keepitvl = tp->keepalive_intvl / HZ; else if (ss->options.tcp.keepitvl != tp->keepalive_intvl / HZ) { oh->status = T_PARTSUCCESS; ss->options.tcp.keepcnt = tp->keepalive_intvl / HZ; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.keepcnt; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_KEEPCNT, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_KEEPCNT; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if (ss->options.tcp.keepcnt == T_UNSPEC) ss->options.tcp.keepcnt = tp->keepalive_probes; else if (ss->options.tcp.keepcnt != tp->keepalive_probes) { oh->status = T_FAILURE; ss->options.tcp.keepcnt = tp->keepalive_probes; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.keepcnt; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_SYNCNT, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_SYNCNT; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if (ss->options.tcp.syncnt == T_UNSPEC) ss->options.tcp.syncnt = tp->syn_retries; else if (ss->options.tcp.syncnt != tp->syn_retries) { oh->status = T_FAILURE; ss->options.tcp.syncnt = tp->syn_retries; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.syncnt; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0); } if (ss_tst_bit(_T_BIT_TCP_LINGER2, ss->options.flags)) { oh->level = T_INET_TCP; oh->name = T_TCP_LINGER2; oh->len = _T_LENGTH_SIZEOF(t_uscalar_t); oh->status = T_SUCCESS; if (ss->options.tcp.linger2 == T_UNSPEC) ss->options.tcp.linger2 = tp->linger2 / HZ; else if (ss->options.tcp.linger2 != tp->linger2 / HZ) { oh->status = T_PARTSUCCESS; ss->options.tcp.linger2 = tp->linger2 / HZ; } *((t_uscalar_t *) T_OPT_DATA(oh)) = ss->options.tcp.linger2; oh = _T_OPT_NEXTHDR_OFS(op, olen, oh, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -