日期:2014-05-16  浏览次数:20727 次

基于Linux系统的边界网关协议的设计与实现
基于Linux系统的边界网关协议的设计与实现
3.6 BGP和RMer系统间通信
RMer系统和BGP系统之间采用的是UNIX本地的服务器客户端模式进行通信,它们创建的socket的地址格式为AF_UNIX,表示用于UNIX本地的通信。RMer系统与BGP系统之间的通信原理如图3-9所示,因为它们之间使用的是本地客户端和服务器模式进行通信,故称RMer系统为local server端,BGP系统为local client端。当BGP服务器和BGP客户端建立TCP连接后,通过调用write和read函数发送和接受RMER报文。

图3-9 RMer和BGP之间的通信
local server程序是通过local_server_start函数实现的,该函数的主要源代码如下。该函数的参数path为local server和local client通信时使用的临时文件"/tmp/.rserv",该文件为socket使用的通信管道。local_server_start函数最后调用thread_add_read函数添加了一个处理函数为rmer_accept的read thread,该thread用于监听来自local client端的连接请求。
void local_server_start (char *path)
{
  int ret;
  int accept_sock, len;
  struct sockaddr_un serv;
  mode_t old_mask;
  unlink (path);    /*删除path所指定的文件,断开和该文件关联的所有socket连接*/
/*设置系统当前的umask值为(0)&(0777),用于设置新创建的文件的访问权限,返回值为系统原来的umask值,由old_mask保存*/
  old_mask = umask (0);
  accept_sock = socket (AF_UNIX, SOCK_STREAM, 0); /*创建一个UNIX domain socket*/
  memset (&serv, 0, sizeof (struct sockaddr_un));
  serv.sun_family = AF_UNIX;
  strncpy (serv.sun_path, path, strlen (path));
  len = sizeof (serv.sun_family) + strlen (serv.sun_path);
  bind (accept_sock, (struct sockaddr *) &serv, len); /*bind操作*/
  listen (accept_sock, 5);       /*listen操作*/
  umask (old_mask); /*恢复系统原来的umask值*/
/*添加一个处理函数为rmer_accept的read thread,监听来自local client端的连接请求*/
  thread_add_read (master, rmer_accept, NULL, accept_sock);
}
rmer_accept函数的主要源代码如下。当TCP连接建立成功后,local server会创建一个struct rserv结构的变量,专门用于和local client进行通信,其中包括读写RMER报文。
int rmer_accept (struct thread *thread)
{
  int accept_sock;
  int client_sock;
  struct sockaddr_in client;
  socklen_t len;
  accept_sock = thread->u.fd;
/*添加一个处理函数为rmer_accept的read thread,监听来自local client端的连接请求*/
  thread_add_read (master, rmer_accept, NULL, accept_sock);
  client_sock = accept (accept_sock, (struct sockaddr *) &client, &sizeof (struct sockaddr_in));
/*根据新建立的TCP连接,创建一个struct rserv结构的变量,负责和local client通信*/
  rmer_client_create (client_sock);
  return 0;
}
当TCP建立成功后,在local server端提供一个struct rserv结构的变量,在local client端提供一个struct rclient结构的变量,二者之间实现通信。相关的数据结构源代码如下。
struct rserv
{
  int sock;      /*local server用来和local client通信的socket*/
  struct stream *ibuf;    /*输入缓存*/
  struct stream *obuf;   /*输出缓存*/
struct thread *t_read;   /*read and write thread*/
  struct thread *t_write; 
  int rtm_table;           /*local client使用的默认路由表*/
  u_char redist[RMER_ROUTE_MAX];     /*重分配信息*/
  u_char redist_default;     
  u_char ifinfo;       /*interface信息*/
};

struct rclient
{
  int sock;  /*local client用来和local server通信的socket*//
  int enable; /*有效位*/
  int fail;   /*连接失败的次数*/
  struct stream *ibuf;    /*输入缓存*/
  struct stream *obuf;   /*输出缓存*/
  struct thread *t_read; /* read and connect thread. */
  struct thread *t_connect;
  u_char redist_default; /*重分配信息*/
  u_char redist[RMER_ROUTE_MAX];
  u_char default_information;
  /*报文处理函数*/
  int (*interface_add) (int, struct rclient *, rmer_size_t);
  int (*interface_delete) (int, struct rclient *, rmer_size_t);
  int (*interface_up) (int, struct rclient *, rmer_size_t);
  int (*interface_down) (int, struct rclient *, rmer_size_t);
  int (*inter