0
点赞
收藏
分享

微信扫一扫

tcp ip 三次握手时数据结构-

tcp ip 三次握手时数据结构-_#define

 

struct tcp_request_sock {
struct inet_request_sock req;
const struct tcp_request_sock_ops *af_specific;
struct skb_mstamp snt_synack; /* first SYNACK sent time */
bool tfo_listener;
u32 txhash;
u32 rcv_isn;
u32 snt_isn;
u32 last_oow_ack_time; /* last SYNACK */
u32 rcv_nxt; /* the ack # by SYNACK. For
* FastOpen it's the seq#
* after data-in-SYN.
*/
};



struct inet_request_sock {
struct request_sock req;
#define ir_loc_addr req.__req_common.skc_rcv_saddr
#define ir_rmt_addr req.__req_common.skc_daddr
#define ir_num req.__req_common.skc_num
#define ir_rmt_port req.__req_common.skc_dport
#define ir_v6_rmt_addr req.__req_common.skc_v6_daddr
#define ir_v6_loc_addr req.__req_common.skc_v6_rcv_saddr
#define ir_iif req.__req_common.skc_bound_dev_if
#define ir_cookie req.__req_common.skc_cookie
#define ireq_net req.__req_common.skc_net
#define ireq_state req.__req_common.skc_state
#define ireq_family req.__req_common.skc_family

kmemcheck_bitfield_begin(flags);
u16 snd_wscale : 4,
rcv_wscale : 4,
tstamp_ok : 1,
sack_ok : 1,
wscale_ok : 1,
ecn_ok : 1,
acked : 1,
no_srccheck: 1;
kmemcheck_bitfield_end(flags);
u32 ir_mark;
union {
struct ip_options_rcu __rcu *ireq_opt;
struct sk_buff *pktopts;
};

};


/* struct request_sock - mini sock to represent a connection request
*/
struct request_sock {
struct sock_common __req_common;
#define rsk_refcnt __req_common.skc_refcnt
#define rsk_hash __req_common.skc_hash
#define rsk_listener __req_common.skc_listener
#define rsk_window_clamp __req_common.skc_window_clamp
#define rsk_rcv_wnd __req_common.skc_rcv_wnd

struct request_sock *dl_next;
u16 mss;
u8 num_retrans; /* number of retransmits */
u8 cookie_ts:1; /* syncookie: encode tcpopts in timestamp */
u8 num_timeout:7; /* number of timeouts */
u32 ts_recent;
struct timer_list rsk_timer;
const struct request_sock_ops *rsk_ops;
struct sock *sk;
u32 *saved_syn;
u32 secid;
u32 peer_secid;
};

 

客户端主动发起连接

  • 调用 socket(2) 创建 TCP socket,tcp_sock 处于 CLOSE 状态
  • tcp ip 三次握手时数据结构-_服务器_02

 

  • 调用 connect(2) 发起连接,tcp_sock 进入 SYN_SENT 状态。
  1. 选择 ephemeral port
  2. 创建 inet_bind_bucket 并加入 bhash
  3. 将 tcp_sock 加入 ehash
  4. 发送 SYN segment

 tcp ip 三次握手时数据结构-_#define_03

 

 

  • 收到服务器发来的 SYN+ACK segment。
  1. 从 ehash 中找到 tcp_sock
  2. 完成握手,进入 ESTABLISHED 状态。数据结构不变,图略。
  3. 发送 ACK segment

 

服务器被动接受连接

  1. 调用 socket(2) 创建 TCP socket,tcp_sock 处于 CLOSE 状态。数据结构如图二。
  2. 调用 bind(2) 将 tcp_sock 加入 bhash。
  3. 调用 listen(2) 将 tcp_sock 设为 LISTEN 状态,并加入 listening_hash。
    这时数据结构的状态如下图:

 

tcp ip 三次握手时数据结构-_服务器_04

 

 

  1. 调用 socket(2) 创建 TCP socket,tcp_sock 处于 CLOSE 状态。数据结构如图二。
  2. 调用 bind(2) 将 tcp_sock 加入 bhash。
  3. 调用 listen(2) 将 tcp_sock 设为 LISTEN 状态,并加入 listening_hash。
    这时数据结构的状态如下图:
    tcp ip 三次握手时数据结构-_#define_05原图:​​​http://chenshuo.github.io/notes/kernel/bhash.png​​
  4. 收到 SYN segment,从 listening_hash 找到 listen tcp_sock,创建 tcp_request_sock(NEW_SYN_RECV 状态),并将其加入 ehash,然后发送 SYN+AC
  5. tcp ip 三次握手时数据结构-_服务器_06收到 ACK segment,从 ehash 中找到 tcp_request_sock,顺藤摸瓜找到 listen tcp_sock,创建新的 tcp_sock(SYN_RECV 状态),将其链入 listen tcp_sock 所属的 inet_bind_bucket 中,然后用它替换 tcp_request_sock 在 ehash 中的位置。接下来把 tcp_request_sock 加入 listen socket 的 accept queue 中,最后经过一系列处理,把新 tcp_sock 设为 ESTABLISHED 状态,可以接收数据了。
  6. tcp ip 三次握手时数据结构-_#define_07用户程序调用 accept(2),从 listen socket 的 accept queue 中取出新 tcp_sock,销毁 tcp_request_sock,然后创建 file/dentry/socket_alloc 等对象将 tcp_sock 加入进程的文件描述符表中,返回相应的文件描述符。

与以前的版本相比,第 4 步改动最大,原来是把 tcp_request_sock 挂在 listen socket 下,收到 ACK 之后从 listening_hash 找到 listen socket 再进一步找到 tcp_request_sock;新的做法是直接把 tcp_request_sock 挂在 ehash 中,这样收到 ACK 之后可以直接找到 tcp_request_sock,减少了锁的争用(contention)。具体的 commit 是:

 

 

http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子

举报

相关推荐

0 条评论