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

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

 bgp = bgp_create(as, name);
bgp_router_id_set(bgp, &router_id_zebra);
*bgp_val = bgp; /* Create BGP server socket, if first instance. */
if (list_isempty(bm->bgp)
&& !bgp_option_check(BGP_OPT_NO_LISTEN)) {
if (bgp_socket(bm->port, bm->address) < ) return BGP_ERR_INVALID_VALUE;
} listnode_add(bm->bgp, bgp);

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

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

 status = bgp_connect(peer);

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

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

 int keylen = password ? strlen(password) : ;
struct tcp_md5sig md5sig;
union sockunion *su2, *susock; ...... memset(&md5sig, , sizeof(md5sig));
memcpy(&md5sig.tcpm_addr, su2, sizeof(*su2));
md5sig.tcpm_keylen = keylen;
if (keylen) memcpy(md5sig.tcpm_key, password, keylen);
sockunion_free(susock); if ((ret = setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig)) < ) {
/* ENOENT is harmless. It is returned when we clear a password for which
one was not previously set. */
if (ENOENT == errno) ret = ;
else zlog_err("sockopt_tcp_signature: setsockopt(%d): %s",
sock, safe_strerror(errno));
}
return ret;

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

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

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

 struct tcp_md5sig {
struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
__u16 __tcpm_pad1; /* zero */
__u16 tcpm_keylen; /* key length */
__u32 __tcpm_pad2; /* zero */
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
};

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

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

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

quagga源码学习--BGP协议对等体连接tcp md5签名认证选项的更多相关文章

  1. quagga源码学习--BGP协议对等体连接建立的状态机

    创建完bgp peer之后,就要bgp start了,不然费那么大劲创建出来不做事情就销毁了,就很尴尬了. 那么对等体一旦start起来,就会进入各自的状态,在不同的状态下处理各自的事件消息. 下面列 ...

  2. quagga源码学习--BGP协议的初始化

    quagga支持BGP-4,BGP-4+协议,支持多协议(mpls,isis,ospf等等)以及单播,组播路由的导入和分发. 具体的协议,这里就不附录了,网络上有很多资料,或者RFC. 协议源码的学习 ...

  3. quagga源码学习--BGP协议中的routemap

    路由策略的基础知识 定义 路由策略(Routing Policy)作用于路由,主要实现了路由过滤和路由属性设置等功能,它通过改变路由属性(包括可达性)来改变网络流量所经过的路径. 目的 路由器在发布. ...

  4. quagga源码学习--BGP协议创建对等体

    现有的路由协议都是通过分布式协议逐个配置协商运行的,协议协议,一个就不需要协议咯,至少2个才能够协议着做事情嘛,不过呢,这样就出现网元过多配置困难的问题,对网管软件要求也越来越高, SDN或许可能改变 ...

  5. quagga源码学习--BGP协议路由更新

    BGP的核心就是交换路由,所以关键的部分还是在路由的更新与撤销上面,这之间包含了冗长的属性,community等等处理过程,不做详述. bgp_read函数是路由更新的事件处理函数,在收到BGP_MS ...

  6. ss源码学习--从协议建立到完成一次代理请求

    上一次介绍了ss源码中各个事件处理函数完成的工作,这次具体分析一下协议的建立以及请求数据的传输过程. 因为ss的local和server共用一个类以及一系列的事件处理函数,所以看起来稍显复杂.下面来将 ...

  7. Dubbo源码学习--服务是如何引用的

    ReferenceBean 跟服务引用一样,Dubbo的reference配置会被转成ReferenceBean类,ReferenceBean实现了InitializingBean接口,直接看afte ...

  8. Dubbo源码学习--服务是如何发布的

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 ServiceBean ServiceBean 实现ApplicationListener接口监听Conte ...

  9. Redis源码学习:字符串

    Redis源码学习:字符串 1.初识SDS 1.1 SDS定义 Redis定义了一个叫做sdshdr(SDS or simple dynamic string)的数据结构.SDS不仅用于 保存字符串, ...

随机推荐

  1. PAT (Advanced Level) 1020. Tree Traversals (25)

    递归建树,然后BFS一下 #include<iostream> #include<cstring> #include<cmath> #include<algo ...

  2. APPIUM安装与搭建Q&A

    APPIUM安装与搭建Q&A Q1:在线安装TESTNG插件时,出现安装失败,提示:Cannot complete the install because one or more requir ...

  3. 实战3--项目开始--准备:::资源分类, 日志系统, 写BaseDao

     项目资源分类: 1.   package: base, dao, dao.impl, domain, service, service.impl, util, view.action 2.   co ...

  4. 用Quick Cocos2dx做一个连连看(一)

    呵呵,不知道能不能坚持下来,先写着吧. 预备知识:Quick Cocos2dx 2.2.5基本知识 或者 Cocos2dx基本知识, lua入门 开发工具:Sublime Text 2.0/3.0 原 ...

  5. SpingMvc 中文乱码 post 方式解决方案

    Web.xml <!-- spring 中文乱码问题 --> <filter> <filter-name>encodingFilter</filter-nam ...

  6. 关于服务器跨域问题(使用cors解决)

    1.配置cors依赖 pom中加入 <dependency> <groupId>com.thetransactioncompany</groupId> <ar ...

  7. iOS中正则表达式的三种使用方式

    1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: NSString *email = @“nijino_saki@163.com”: NSString *regex = @"[ ...

  8. JAVA判断32位还是64位,调用不同的DLL(转)

    源:JAVA判断32位还是64位,调用不同的DLL 通过获取sun.arch.data.model可判断是32还是64的JAVA 将32或者64位的DLL放不同的目录,实现自适应调用DLL Prope ...

  9. 处理JSON格式的数据

    JSON格式的数据是最常用的数据格式,处理方法的选择就显得比较重要了.我常用的一种是用对象来接收,然后保存在数组中,需要时直接从数组中取值.下面列出一个小例子. .h文件中: #import < ...

  10. <libxml2/tree.h> file not found

    Build Settings: head search paths :$(inherited) /usr/include/libxml2 Build phases: 加上libxml2.tbd