本文主要分析:在收到客户端的SYN包时,服务器端是如何解析它所携带的TCP选项,并结合本端情况决定是否予以支持。
内核版本:3.6
Author:zhangskd @ csdn blog
概述
收到客户端的SYN包时,需要全面的解析它携带的TCP选项,这样我们就知道客户端支持哪些选项,如果本端也支持,
那么连接就支持这些TCP选项。这些信息在连接建立的过程中,是保存在连接请求块的(request_sock、inet_request_sock、
tcp_request_sock)。
函数调用路径:
tcp_v4_conn_request
|--> tcp_parse_options
3.6版本Linux内核支持的TCP选项包括:
NOP,用于填充。
Max Segment Size,最大分段大小。
Window Scaling,窗口扩大因子。
SACK Permit,是否允许使用SACK。
SACK,携带SACK块。
Timestamp,时间戳选项。
MD5SIG,MD5签名。
Cookie,Cookie extension,2013年3月已从内核移除。
EXP,Experimental,处于实验阶段的选项,新版本用于Fast Open。
实现
全面解析数据包的TCP选项,并保存到指定的tcp_options_received实例中。
-
-
#define TCPOPT_NOP 1
-
#define TCPOPT_EOL 0
-
#define TCPOPT_MSS 2
-
#define TCPOPT_WINDOW 3
-
#define TCPOPT_TIMESTAMP 8
-
#define TCPOPT_SACK_PERM 4
-
#define TCPOPT_SACK 5
-
#define TCPOPT_MD5SIG 19
-
#define TCPOPT_COOKIE 253
-
#define TCPOPT_EXP 254
-
-
-
-
-
#define TCPOPT_FASTOPEN_MAGIC 0xF989
-
-
-
#define TCPOLEN_MSS 4
-
#define TCPOLEN_WINDOW 3
-
#define TCPOLEN_TIMESTAMP 10
-
#define TCPOLEN_SACK_PERM 2
-
#define TCPOLEN_COOKIE_BASE 2
-
#define TCPOLEN_COOKIE_PAIR 3
-
#define TCPOLEN_COOKIE_MIN (TCPOLEN_COOKIE_BASE + TCP_COOKIE_MIN)
-
#define TCPOLEN_COOKIE_MAX (TCPOLEN_COOKIE_BASE + TCP_COOKIE_MAX)
-
#define TCPOLEN_EXP_FASTOPEN_BASE 4
-
-
-
#define TCP_SACK_SEEN (1 << 0)
-
#define TCP_FACK_ENABLED (1 << 1)
-
#define TCP_DSACK_SEEN (1 << 2)
-
-
-
#define TCP_COOKIE_MIN 8
-
#define TCP_COOKIE_MAX 16
-
-
-
#define TCP_FASTOPEN_COOKIE_MIN 4
-
#define TCP_FASTOPEN_COOKIE_MAX 16
-
-
-
struct tcp_fastopen_cookie {
-
s8 len;
-
u8 val[TCP_FASTOPEN_COOKIE_MAX];
-
};
-
-
static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
-
{
-
rx_opt->dsack = 0;
-
rx_opt->num_sacks = 0;
-
}
用于判断连接是否使用ECN。要注意的是在建立连接时,要求IP报的ECN域不能被设置,否则就禁用ECN。
-
-
-
-
-
-
-
static inline void TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb)
-
{
-
const struct tcphdr *th = tcp_hdr(skb);
-
-
if (sysctl_tcp_ecn && th->ece && th->cwr && INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield))
-
inet_rsk(req)->ecn_ok = 1;
-
}
清零TCP选项。
-
static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
-
{
-
rx_opt->tstamp_ok = rx_opt->sack_ok = 0;
-
rx_opt->wscale_ok = rx_opt->snd_wscale = 0;
-
rx_opt->cookie_plus = 0;
-
}
阅读(1453) | 评论(0) | 转发(0) |