日期:2014-05-16 浏览次数:20815 次
注意 tcp_ack 是来处理接收到的ACK的,那么到底怎么去做呢?看下面:
先还上把tcp_sock的结构放在这里,下面一些数据的分析需要用到:
struct tcp_sock { /* inet_connection_sock has to be the first member of tcp_sock */ struct inet_connection_sock inet_conn; u16 tcp_header_len; /* Bytes of tcp header to send */ // tcp头部长度 u16 xmit_size_goal_segs; /* Goal for segmenting output packets */// 分段数据包的数量 /* * Header prediction flags * 0x5?10 << 16 + snd_wnd in net byte order */ __be32 pred_flags; // 头部预置位(用于检测头部标识位处理ACK和PUSH之外还有没有其他位,从而判断是不是可以使用快速路径处理数据) /* * RFC793 variables by their proper names. This means you can * read the code and the spec side by side (and laugh ...) * See RFC793 and RFC1122. The RFC writes these in capitals. */ u32 rcv_nxt; /* What we want to receive next */ // 下一个想要收到的第一个数据的字节编号 u32 copied_seq; /* Head of yet unread data */ // 没还有读出的数据的头 u32 rcv_wup; /* rcv_nxt on last window update sent */ // rcv_nxt在最后一个窗口更新时的值 u32 snd_nxt; /* Next sequence we send */ // 下一个发送的第一个字节编号 u32 snd_una; /* First byte we want an ack for */ // 对于发出的数据,都需要对方的ACK,这里标示当前需要被确认的第一个字节 u32 snd_sml; /* Last byte of the most recently transmitted small packet */ // 最近发送的小数据包的最后一个字节 u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */ // 最后一次接收到ACK的时间戳 u32 lsndtime; /* timestamp of last sent data packet (for restart window) */ // 最后一次发送数据包时间戳 u32 tsoffset; /* timestamp offset */ // 时间戳偏移 struct list_head tsq_node; /* anchor in tsq_tasklet.head list */ // unsigned long tsq_flags; // 注意下面这个ucopy:就是将用户数据从skb中拿出来放进去,然后传给应用进程!!! /* Data for direct copy to user */ struct { struct sk_buff_head prequeue; // 预处理队列 struct task_struct *task; // 预处理进程 struct iovec *iov; // 用户程序(应用程序)接收数据的缓冲区 int memory; // 用于预处理计数 int len; // 预处理长度 #ifdef CONFIG_NET_DMA /* members for async copy */ struct dma_chan *dma_chan; int wakeup; struct dma_pinned_list *pinned_list; dma_cookie_t dma_cookie; #endif } ucopy; // snd_wl1:记录发送窗口更新时,造成窗口更新的那个数据报的第一个序号。 它主要用于在下一次判断是否需要更新发送窗口。 u32 snd_wl1; /* Sequence for window update */ // 窗口更新序列号( 每一次收到确认之后都会改变 ) u32 snd_wnd; /* The window we expect to receive */ // 我们期望收到的窗口 u32 max_window; /* Maximal window ever seen from peer */ // 从对方接收到的最大窗口 u32 mss_cache; /* Cached effective mss, not including SACKS */ // 有效的MSS,SACKS不算 u32 window_clamp; /* Maximal window to advertise */ // 对外公布的最大的窗口 u32 rcv_ssthresh; /* Current window clamp */ // 当前窗口值 u16 advmss; /* Advertised MSS */ // 对外公布的MSS u8 unused; u8 nonagle : 4,/* Disable Nagle algorithm? */ // Nagle算法是否有效 thin_lto : 1,/* Use linear timeouts for thin streams */ // 使用线性超时处理 thin_dupack : 1,/* Fast retransmit on first dupack */ // 收到第一个重复的ACK的时候是否快速重传 repair : 1,