Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1785757
  • 博文数量: 306
  • 博客积分: 3133
  • 博客等级: 中校
  • 技术积分: 3932
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-19 16:50
文章分类

全部博文(306)

文章存档

2018年(7)

2017年(18)

2016年(39)

2015年(35)

2014年(52)

2013年(39)

2012年(22)

2011年(29)

2010年(53)

2009年(12)

分类: LINUX

2010-03-19 11:35:12

/usr/src/linux-2.6.28/net/ipv4/tcp.c

switch (optname) {
    case TCP_MAXSEG:
        /* Values greater than interface MTU won't take effect. However
         * at the point when this call is done we typically don't yet
         * know which interface is going to be used */
        if (val < 8 || val > MAX_TCP_WINDOW) {
            err = -EINVAL;
            break;
        }
        tp->rx_opt.user_mss = val;
        break;

    case TCP_NODELAY:
        if (val) {
            /* TCP_NODELAY is weaker than TCP_CORK, so that
             * this option on corked socket is remembered, but
             * it is not activated until cork is cleared.
             *
             * However, when TCP_NODELAY is set we make
             * an explicit push, which overrides even TCP_CORK
             * for currently queued segments.
             */
            tp->nonagle |= TCP_NAGLE_OFF|TCP_NAGLE_PUSH;
            tcp_push_pending_frames(sk);
        } else {
            tp->nonagle &= ~TCP_NAGLE_OFF;
        }
        break;

    case TCP_CORK:
        /* When set indicates to always queue non-full frames.
         * Later the user clears this option and we transmit
         * any pending partial frames in the queue.  This is
         * meant to be used alongside sendfile() to get properly
         * filled frames when the user (for example) must write
         * out headers with a write() call first and then use
         * sendfile to send out the data parts.
         *
         * TCP_CORK can be set together with TCP_NODELAY and it is
         * stronger than TCP_NODELAY.
         */
        if (val) {
            tp->nonagle |= TCP_NAGLE_CORK;
        } else {
            tp->nonagle &= ~TCP_NAGLE_CORK;
            if (tp->nonagle&TCP_NAGLE_OFF)
                tp->nonagle |= TCP_NAGLE_PUSH;
            tcp_push_pending_frames(sk);
        }
        break;

    case TCP_KEEPIDLE:
        if (val < 1 || val > MAX_TCP_KEEPIDLE)
            err = -EINVAL;
        else {
            tp->keepalive_time = val * HZ;
            if (sock_flag(sk, SOCK_KEEPOPEN) &&
                !((1 << sk->sk_state) &
                  (TCPF_CLOSE | TCPF_LISTEN))) {
                __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp;
                if (tp->keepalive_time > elapsed)
                    elapsed = tp->keepalive_time - elapsed;
                else
                    elapsed = 0;
                inet_csk_reset_keepalive_timer(sk, elapsed);
            }
        }
        break;
    case TCP_KEEPINTVL:
        if (val < 1 || val > MAX_TCP_KEEPINTVL)
            err = -EINVAL;
        else
            tp->keepalive_intvl = val * HZ;
        break;
    case TCP_KEEPCNT:
        if (val < 1 || val > MAX_TCP_KEEPCNT)
            err = -EINVAL;
        else
            tp->keepalive_probes = val;
        break;
    case TCP_SYNCNT:
        if (val < 1 || val > MAX_TCP_SYNCNT)
            err = -EINVAL;
        else
            icsk->icsk_syn_retries = val;
        break;

    case TCP_LINGER2:
        if (val < 0)
            tp->linger2 = -1;
        else if (val > sysctl_tcp_fin_timeout / HZ)
            tp->linger2 = 0;
        else
            tp->linger2 = val * HZ;
        break;

    case TCP_DEFER_ACCEPT:
        icsk->icsk_accept_queue.rskq_defer_accept = 0;
        if (val > 0) {
            /* Translate value in seconds to number of
             * retransmits */
            while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
                   val > ((TCP_TIMEOUT_INIT / HZ) <<
                       icsk->icsk_accept_queue.rskq_defer_accept))
                icsk->icsk_accept_queue.rskq_defer_accept++;
            icsk->icsk_accept_queue.rskq_defer_accept++;
        }
        break;

    case TCP_WINDOW_CLAMP:
        if (!val) {
            if (sk->sk_state != TCP_CLOSE) {
                err = -EINVAL;
                break;
            }
            tp->window_clamp = 0;
        } else
            tp->window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
                        SOCK_MIN_RCVBUF / 2 : val;
        break;

    case TCP_QUICKACK:
        if (!val) {
            icsk->icsk_ack.pingpong = 1;
        } else {
            icsk->icsk_ack.pingpong = 0;
            if ((1 << sk->sk_state) &
                (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) &&
                inet_csk_ack_scheduled(sk)) {
                icsk->icsk_ack.pending |= ICSK_ACK_PUSHED;
                tcp_cleanup_rbuf(sk, 1);
                if (!(val & 1))
                    icsk->icsk_ack.pingpong = 1;
            }
        }
        break;

#ifdef CONFIG_TCP_MD5SIG
    case TCP_MD5SIG:
        /* Read the IP->Key mappings from userspace */
        err = tp->af_specific->md5_parse(sk, optval, optlen);
        break;
#endif

    default:
        err = -ENOPROTOOPT;
        break;
    }
阅读(2094) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~