WEB开发网
开发学院软件开发Java tcp connection setup的实现(二) 阅读

tcp connection setup的实现(二)

 2009-09-10 00:00:00 来源:WEB开发网   
核心提示: 接下来来看tcp_v4_conn_request的实现, Java代码 inttcp_v4_conn_request(structsock*sk,structsk_buff*skb){structinet_request_sock*ireq;structtcp_options_receivedt

接下来来看tcp_v4_conn_request的实现,

Java代码

int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 
{ 
 struct inet_request_sock *ireq; 
 struct tcp_options_received tmp_opt; 
 struct request_sock *req; 
 __be32 saddr = ip_hdr(skb)->saddr; 
 __be32 daddr = ip_hdr(skb)->daddr; 
///这个名字实在是无语,when具体表示什么不太理解,只是知道它是用来计算rtt的. 
 __u32 isn = TCP_SKB_CB(skb)->when; 
 struct dst_entry *dst = NULL; 
#ifdef CONFIG_SYN_COOKIES 
 int want_cookie = 0; 
#else 
#define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */ 
#endif 
 
///如果是广播或者多播,则丢掉这个包. 
 if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) 
 goto drop; 
 
///判断半连接队列是否已经满掉.如果满掉并且处于非timewait状态,则丢掉这个包(如果设置了SYN Cookie则会继续进行,因为SYN Cookie不需要新分配半连接队列,详细的SYN Cookie请google) 
 if (inet_csk_reqsk_queue_is_full(sk) && !isn) { 
#ifdef CONFIG_SYN_COOKIES 
 if (sysctl_tcp_syncookies) { 
  want_cookie = 1; 
 } else 
#endif 
 goto drop; 
 } 
///如果accept队列已满,并且qlen_young大于一就丢掉这个包,这里qlen_young大于一表示在syn队列中已经有足够多的(这里不包括重传的syn)请求了. 
 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) 
 goto drop; 
 req = inet_reqsk_alloc(&tcp_request_sock_ops); 
 if (!req) 
 goto drop; 
................................................... 
 
///对tmp_opt进行初始化,而tcp_options_received中包含了tcp的一些选项信息(比如mss,窗口扩大因子等等) 
 tcp_clear_options(&tmp_opt); 
 tmp_opt.mss_clamp = 536; 
 tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss; 
 
///对对端的tcp_options_received进行解析,并对本端得tcp_options_received进行初始化. 
 tcp_parse_options(skb, &tmp_opt, 0); 
 
....................................................... 
///这里对新的req进行初始化. 
 
 tcp_openreq_init(req, &tmp_opt, skb); 
............................................... 
 
///这里将tcp_options_received保存到req中. 
 ireq->opt = tcp_v4_save_options(sk, skb); 
 if (!want_cookie) 
 TCP_ECN_create_request(req, tcp_hdr(skb)); 
 
 if (want_cookie) { 
#ifdef CONFIG_SYN_COOKIES 
 syn_flood_warning(skb); 
 req->cookie_ts = tmp_opt.tstamp_ok; 
#endif 
 isn = cookie_v4_init_sequence(sk, skb, &req->mss); 
 }else if (!isn) { 
............................................. 
///计算当前一个合适的isn,并返回. 
 isn = tcp_v4_init_sequence(skb); 
 } 
 
///赋值发送给对端的isn 
 tcp_rsk(req)->snt_isn = isn; 
 
///发送syn和ack(如果设置了want_cookie则不会将这个req链接到半连接队列中. 
 if (__tcp_v4_send_synack(sk, req, dst) || want_cookie) 
 goto drop_and_free; 
 
///将这个req链接到半连接队列中. 
 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 
 return 0; 
 
drop_and_release: 
 dst_release(dst); 
drop_and_free: 
 reqsk_free(req); 
drop: 
 return 0; 
}

上一页  1 2 3 4 5 6 7 8 9  下一页

Tags:tcp connection setup

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接