android vpn 分析

来源:互联网 发布:php网站源码 编辑:程序博客网 时间:2024/04/30 08:59

以下是转载:

1. VPN related source code in Froyo.
1.1 java layer:
a. UI source code:
packages/apps/Settings/src/com/android/settings/vpn
b. vpn server source code:
frameworks/base/vpn/java/android/net/vpn
framework/base/packages/vpnservices/src/com/android/server/vpn

1.2 native layer:
external/mtpd: used to control pptp and l2tp modules.
external/ipsec-tools: used to configure ipsec.
of cause, it will use pppd, which is in /external/ppp/.

1.3 driver layer:
Apart from the feature in standard linux kernel, Google adds the below two files for pptp and l2tp.
driver/net/pppopns.c: for ppp over pptp.
driver/net/pppolac.c: for ppp over l2tp.

2. Java layer.
VPN Java layer is responsible for VPN configuration, it can be divided into two sub-layers, the upper layer is VPN settings, the lower layer is VPN service which is in framework.
VPN Java layer has two interfaces to impact native layer,
a. it uses Daemon class to start / stop two daemons, these two daemons are: mtpd and racoon.
mtpd is for pptp and l2tp. 
racoon is for ipsec.
b. it uses local socket to communicate with native layer. VPN Java layer uses this local socket to do two things.
the first is to send launch parameters to mtpd or racoon deamon.
the second is to receive the status of mtpd.
in addition, java layer will read the status of VPN from system property - "vpn.status" which is writen by ip-up-vpn.
the VPN profiles is saved in /misc/vpn/profiles/ folder.

3. Native layer.
as we said in Java layer, mtpd and racoon daemon are launched by Java layer, what is more, Java layer also send launch parameter to these daemon by local socket.
for mtpd daemon, the local socket server file is /dev/socket/mtpd.
for racoon deamon, the local socket server file is /dev/socket/racoon.
in fact, we can launch these daemon by command line which can emulate Java layer's operation.
the below is a example:
mtpd pptp 192.168.1.32 1723 '' linkname vpn name 111 password 222 refuse-eap nodefaultroute usepeerdns idle 1800 mtu 1300 mru 1300 +mppe &
mtpd l2tp 192.168.1.32 1701 '' linkname vpn name 111 password 222 refuse-eap nodefaultroute usepeerdns idle 1800 mtu 1300 mru 1300 &

the usage of Mtpd and Racoon are as below.
#mtpd
Usage: mtpd <protocol-args> '' <pppd-args>, where protocol-args are one of:
       l2tp <server> <port> [secret]
       pptp <server> <port>

# racoon
Usage: racoon server port pre-shared-key
       racoon server port my-private-key my-cert ca-cert

How does mtpd control driver layer to enable /disable VPN link, let us focus on it and continue it in the second part.

In Froyo, there are four types of VPN.
PPTP VPN.
L2TP VPN.
L2TP/IPsec PSK VPN.
L2TP/IPsec CRT VPN.

the below describes the principle of PPTP VPN, we divide main process into two planes: control plane and data plane, control plane describes how to set up PPTP VPN and prepares for data plane. data plane describes data transmission.

1. control plane
while mtpd is launched, it will do the below things:
a. use get_control_and_arguments() to set up local socket, then receive boot parameter from Java layer, and divide the boot parameter into two parts: one is for itself, another is for PPP daemon.
b. use initialize() to do initialization, according to boot parameter, it will call pptp or l2tp 's connect() funciton, for pptp, the function is pptp_connect() function.
timeout = the_protocol->connect(argc - 2, &argv[2]);
c. in pptp_connect() function, it creates a stream socket to setup a link which connects to pptp server by using TCP protocol and 1723 port, and then send SCCRQ message.
d. use poll() function to receive message from pptp server, and then call pptp_process() to process message.
e. once the pptp link is established, it will call start_pppd() to launch pppd daemon, however, it need call create_pppox() to create pppox handle firstly.
f. in create_pppox() function, it uses the below sentence to create a AF_PPPOX type socket, 
socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OPNS);
and then call connect() function which will call pppopns_connect() function in /driver/net/pppopns.c of kernel in fact, the input parameter type is 
        struct sockaddr_pppopns address = {
            .sa_family = AF_PPPOX,
            .sa_protocol = PX_PROTO_OPNS,
            .tcp_socket = the_socket,
            .local = local,
            .remote = remote,
        };
in this struct, the_socket is included which contains the info about pptp server. so kernel can use these info to setup GRE socket for VPN data plane.

The above describes mtpd daemon, now let us focus on kernel layer.

g. while kernel is launched, pppopns_init() function is called, in this function, it will call proto_register() and register_pppox_proto() to register pppopns protocol.
h. as we said in 'f' item, mtpd calls pppopns_connect() function, in this function, it use socket_create() to generate a GRE link to pptp server which is used to encapsulate ppp package, and then set &pppopns_channel_ops for po->chan.ops, and also set pppopns_recv() for sk_raw->sk_data_ready. so now pppopns_xmit() which is responsible for transmiting package and pppopns_recv() which is responsible for receiving package is installed successfully.
till now GRE tunnel is ready for PPP package.

2. Date plane
a. while pppd daemon is launched, it will execute normal ppp process, such as LCP, NCP, and also IP package at last.
while PPP package is ready, kernel will call pppopns_xmit() function which has already been registered into kernel.
b. in pppopns_xmit() function, this PPP package will be as a GRE payload, and be sent to pptp server by using GRE tunnel, so now the package's format is as below:
| L1 | L2 | IP | GRE | PPP |
Please note: this PPP message contains PPP, IP and upper layer data.
c. while package is received from pptp server, the package will be parsed as a normal GRE package, for GRE raw data, it will be transfered to pppopns_recv() funciton.
d. in pppopns_recv(), the raw PPP package will be transfered to ppp_input() function.


0 0
原创粉丝点击