随笔分类 - 开发Vtun源码分析
基于虚拟网卡的VPN源码分析
摘要:1 /***************************************** 2 * Name : Vtun 源码详细分析 3 * Version : 3.0.3 4 * Date : Jan. 22, 2014 5 * Author : lucas 6 * Email : lucasysfeng@gmail.com 7 * Blog : http://www.cnblogs.com/lucasysfeng/ 8 * Description : 1.Vtun是一个短小精悍的开源VPN项目, ...
阅读全文
摘要:sudo ip route flush table main
阅读全文
摘要:client.c文件中在建立socket后有一句 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); SO_REUSEADDR允许重用本地地址。 client.c文件在bind之后的connec_t函数中, 先将socket设为非阻塞,然后connect 然后select然后再将socket状态改为原来的。 这样做的目的是se...
阅读全文
摘要:在main函数中,reread_config(0); 经过下面的分析,知reread_config(0);是将每个会话信息作为一个结点存于host_list中(一个会话信息包含默认信息和本会话特有信息,且本会话信息会覆盖默认的相同选项)。 void reread_config(int sig){ if( !read_config(vtun.cfg_file) ) { vtun_syslog(LOG...
阅读全文
摘要:struct llist_element { struct llist_element * next; void * data;}; typedef struct llist_element llist_elm; llist_elm是一个链表型结点。 typedef struct { llist_elm * head; llist_elm * tail;} llist; llist结构体中...
阅读全文
摘要:认证即隧道的建立用TCP套接字,之后根据配置文件选择合适协议传输。 clinet隧道建立套接字和传输套接字替换 1、在clinet函数中 s = socket(AF_INET,SOCK_STREAM,0); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bind(s,(struct sockaddr *)&my_addr,s...
阅读全文
摘要:只分析udp, 单独运行clinet,处于connect状态,并没有运行到tunnel这个步骤,单独运行client时没出现虚拟网卡; 单独运行server,处于listen状态,也没运行到tunnel这个步骤,所以单独运行server也不会出现虚拟新网卡。 当server端开启,处于监听状态,这时client请求连接,认证成功后client和server才会进入tunnel执行打开虚拟网卡, ...
阅读全文
摘要:openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); 打开系统记录 在lib.c中定义, void vtun_syslog (int priority, char *format, ...) { static volatile sig_atomic_t in_syslog= 0; char buf[255]; va...
阅读全文
摘要:1、__io_canceled在lib.h中定义, /* IO cancelation */extern volatile sig_atomic_t __io_canceled; __io_canceled变量影响下列函数, static inline int read_n(int fd, char *buf, int len){ register int t=0, w; while (!_...
阅读全文
摘要:在main函数中,有一行, clear_nat_hack_flags(svr); 在cfg_file.y中定义, /* Clear the VTUN_NAT_HACK flag which are not relevant to the current operation mode */inline void clear_nat_hack_flags(int svr){ if (svr) llis...
阅读全文
摘要:声明:转载注明出处! 注: 1、 PID文件 the pid files contains the process id (a number) of a given program. For example, Apache HTTPD may write it's main process number to a pid file - which is a regular text file,...
阅读全文
摘要:头文件:#include<unistd.h>#include<sys/types.h>原型:pid_t fork( void);返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1.功能:一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。举例1234567891011121314151617181920212223#include<sys/types.h>//对于
阅读全文
摘要:上一篇分析了linkfd.c的lfd_linker()函数中的while在不考虑信号中断的情况下一直在执行(执行的是虚拟网卡的读写和数据的发送接收)。 而决定是否一直循环执行的linker_term变量被信号处理函数改变了,下面分析linker_term在哪些信号处理函数中被改变了,以及信号处理函数在干嘛。 在linkfd.c中, /* Termination flag */ static voi...
阅读全文
摘要:在文件linkfd.c文件中,有从虚拟网卡读出数据然后发送,将接收到的数据写入网卡过程。 注意,在client和server端,上面的两个过程都有,意思可以说是两端对等,看下图。 下面分析对虚拟网卡的读写非阻塞问题,在linkfd.c的lfd_linker函数中,(client和server都是用该函数完成对虚拟网卡的读写)。 主要是下面代码: while( !linker_term )//w...
阅读全文
摘要:下面分析使用UDP封装数据包发送流程,从udp的socket创建开始分析, client中调用tunnel函数,tunnel中调用linkfd完成数据的发送。 发送数据流程都在linkfd.c中,这里的发送指的是从虚拟网卡读出数据,作为新建socket的数据部分发送。 linkfd函数中调用lfd_linker函数,其中有数据包的发送函数, if( len && proto_write(fd1, out, len) < 0 ) 那么建立数据包的和连接的过程在哪里?这就要分析fd1了, 下面分析fd1, int fd1 = lfd_host->rmt_fd; 找lfd
阅读全文
摘要:一、下面分析client端的认证函数(认证过程就是隧道建立过程) 函数client和server分别在文件client.c和server.c中,先分析client. if( (s = socket(AF_INET,SOCK_STREAM,0))==-1 )。。。 隧道使用sock_STREAM建立的,但是隧道中数据的传输可用TCP也可用UDP。 if( bind(s,(struct sockadd...
阅读全文
摘要:怀疑vtun就是将虚拟网卡中的数据读出,然后新建socket发送该数据的。 从上一篇看到了数据包的发送和接收是通过调用 proto_write proto_read两个函数实现的,那么我们就来看这两个函数,进一步了解vtun是如何封装和解封也即发送接收数据的。 一、proto_write封装分析 proto_write是函数指针,在tunnel.c中: proto_write = udp_write;proto_read = udp_read; 先看udp_write函数,udp_proto.c中: /* Functions to read/write UDP frames. */in...
阅读全文
摘要:一、对虚拟网卡的读写操作都在哪里? 对虚拟网卡写操作函数tun_write在tun_dev.c中定义; 函数指针dev_write在tunnel.c中指向tun_write函数; 函数指针dev_write在linkfd.c中对虚拟网卡进行写操作。 因此实际对虚拟网卡的写操作在linkfd.c中。 涉及到写操作的linkfd.c中的代码: if( len && dev_write(fd2,ou...
阅读全文

浙公网安备 33010602011771号