bgp使用tcp连接,每个bgp实例自身是peer的一个tcp server端,同时也是peer的tcp client端。

1、在bgp_create之后都建立自己的socket服务端开始监听179端口:

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

 1 bgp = bgp_create(as, name); 2     bgp_router_id_set(bgp, &router_id_zebra); 3     *bgp_val = bgp; 4  5     /* Create BGP server socket, if first instance.  */ 6     if (list_isempty(bm->bgp) 7         && !bgp_option_check(BGP_OPT_NO_LISTEN)) { 8         if (bgp_socket(bm->port, bm->address) < 0) return BGP_ERR_INVALID_VALUE; 9     }10 11     listnode_add(bm->bgp, bgp);

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

bgp_socket里完成server socket的创建与监听。

 

2、在bgp_start函数里开始对peer的connect操作。在connect之前会清楚一些peer的设置,避免与上一个连接session的混淆。

 status =

如果定义了HAVE_DECL_TCP_MD5SIG宏,或者更老的linux 2.4内核版本的宏 HAVE_TCP_MD5_LINUX24,即会添加TCP MD5签名验证选项。

为了跟上时代的步伐,这里我们就只看高版本的内核了。

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

 1 int keylen = password ? strlen(password) : 0; 2     struct tcp_md5sig md5sig; 3     union sockunion *su2, *susock; 4      5     ...... 6      7     memset(&md5sig, 0, sizeof(md5sig)); 8     memcpy(&md5sig.tcpm_addr, su2, sizeof(*su2)); 9     md5sig.tcpm_keylen = keylen;10     if (keylen) memcpy(md5sig.tcpm_key, password, keylen);11     sockunion_free(susock);12 13     if ((ret = setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig)) < 0) {14         /* ENOENT is harmless.  It is returned when we clear a password for which15        one was not previously set. */16         if (ENOENT == errno) ret = 0;17         else zlog_err("sockopt_tcp_signature: setsockopt(%d): %s",18                       sock, safe_strerror(errno));19     }20     return ret;

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

上面的代码即完成MD5SIG选项。

如果md5值不正确或者密码错误,内核会丢弃当前的报文。

4.1.3版本内核对md5sig的结构定义:

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

1 struct tcp_md5sig {2     struct __kernel_sockaddr_storage tcpm_addr;    /* address associated */3     __u16    __tcpm_pad1;                /* zero */4     __u16    tcpm_keylen;                /* key length */5     __u32    __tcpm_pad2;                /* zero */6     __u8    tcpm_key[TCP_MD5SIG_MAXKEYLEN];        /* key (binary) */7 };

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

在int tcp_v4_rcv(struct sk_buff *skb)函数里:

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

 1 #ifdef CONFIG_TCP_MD5SIG 2     /* 3      * We really want to reject the packet as early as possible 4      * if: 5      *  o We're expecting an MD5'd packet and this is no MD5 tcp option 6      *  o There is an MD5 option and we're not expecting one 7      */ 8     if (tcp_v4_inbound_md5_hash(sk, skb)) 9         goto discard_and_relse;10 #endif

万码学堂,电脑培训,计算机培训,Java培训,JavaEE开发培训,青岛软件培训,软件工程师培训

因此在服务端,直接由内核在tcp接收处理时就完成了签名验证。

 

http://www.cnblogs.com/danxi/p/6351384.html

网友评论

更多精彩分享

万码学堂联系方式-Java培训机构,青岛Java培训,青岛计算机培训,软件编程培训,seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训,Java培训万码学堂联系方式