日期:2014-05-16 浏览次数:20960 次
注意 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,