My Octopress Blog

A blogging framework for hackers.

Android-VPN-Howto

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: 1. setup local socket and obtain boot parameters from Java. 2. initialize and connect pptp_connect() or l2tp_connect() 3. create a stream socket to setup a link and connect to pptp server. 4. use poll() to receive message from pptp server, handle it with pptp_process(). 5. launch ppd daemon once pptp link is established. 6. create a AF_PPPOX socket The above describes mtpd daemon, now let us focus on kernel layer. 7. 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. 8. 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

  1. 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.
  2. 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.
  3. 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.
  4. in pppopns_recv(), the raw PPP package will be transfered to ppp_input() function.

This document comes from the link in [1].

Reference: [1] http://blog.csdn.net/linweig/article/details/6127270

Week Reference - What Is It and How to Use It ?

In XPCOM, a weak reference is a special object that contains a pointer to an XPCOM object, but does not keep that object alive. If the referent object is destroyed before the weak reference, the pointer inside the weak reference is set to nsnull.

How do I use it?

Here’s an example. The new and interesting things are highlighted.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "nsWeakPtr.h"
#include "nsIWeakReferenceUtils.h"
// ...

// it's easy to get a weak reference...
nsWeakPtr weakPtr = do_GetWeakReference(aFooPtr);

// ...

{   // ...but to use my weak reference, I'll need a (short-lived) owning reference
  nsCOMPtr<nsIFoo> tempFooPtr = do_QueryReferent(weakPtr);
  if ( tempFooPtr )
    tempFooPtr->SomeFooMethod(...);
  // else, the `real' object has gone away
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class nsObservable
  {
    public:
      // ...
      nsresult AddObserver( nsIObserver* );
      nsresult NotifyObservers( nsIMessage* );
      // ...
    private:
      nsWeakPtr mObserver;
      // ...or imagine a list of observers here
  };

// ...

nsresult
nsObservable::AddObserver( nsIObserver* aObserver )
  {
    mObserver = getter_AddRefs( NS_GetWeakReference(aObserver) );
      // ...or append this to the list of observers
    return NS_OK;
  }

nsresult
nsObservable::NotifyObservers( nsIMessage* aMessage )
  {
    nsCOMPtr<nsIObserver> observer = do_QueryReferent(mObserver);
    if ( observer )
      observer->NoticeMessage(aMessage);
    else
      mObserver = 0;
      // or remove this observer from the list, he's gone away
    return NS_OK;
  }

// ...

Octopress Blog Howto

Create a new article.

1
2
bundle exec rake new_post['Title of your post'] or
rake new_post['Title of your post']

Preview your Blog.

1
2
bundle exec rake preview or
rake preview

Deploy your articles to Blog

1
2
3
4
$ bundle exec rake generate
$ bundle exec rake deploy  or
$ rake generate
$ rake deploy

JavaScript - Typed Arrays, ArrayBuffer and DataView

JavaScript - 

Typed arrays

It has become clear that there are times when it would be helpful for JavaScript code to be able to quickly and easily manipulate raw binary data.In the past, this had to be simulated by treating the raw data as a string and using the charCodeAt() method to read the bytes from the data buffer.

Consider this C structure:

1
2
3
4
5
struct someStruct {
  unsigned long id;
  char username[16];
  float amountDue;
};

You can access a buffer containing data in this format like this:

1
2
3
4
5
var buffer = new ArrayBuffer(24);
// ... read the data into the buffer ...
var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);

ArrayBuffer

The ArrayBuffer is a data type that is used to represent a generic, fixed-length binary data buffer. You can’t directly manipulate the contents of an ArrayBuffer; instead, you create an ArrayBufferView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.

1
var buf = new ArrayBuffer(32);

DataView

An ArrayBuffer is a useful object for representing an arbitrary chunk of data. In many cases, such data will be read from disk or from the network, and will not follow the alignment restrictions that are imposed on the Typed Array Views described earlier. In addition, the data will often be heterogeneous in nature and have a defined byte order. The DataView view provides a low-level interface for reading such data from and writing it to an ArrayBuffer.

1
2
3
4
5
6
7
8
let buffer = new ArrayBuffer(NTP_PACKET_SIZE);
let data = new DataView(buffer);
// Set the first byte.
data.setUint8(0, NTP_MODE_CLIENT | (NTP_VERSION &lt;&lt; 3));
// Set the 40th byte. 
data.setUint32(TRANSMIT_TIME_OFFSET, s, false);
// Set the 44th byte. 
data.setUint32(TRANSMIT_TIME_OFFSET+4, f, false);

Trick to check the Endian type of architecture your script is running: 

1
2
3
4
5
var littleEndian = (function() {
  var buffer = new ArrayBuffer(2);
  new DataView(buffer).setInt16(0, 256, true);
  return new Int16Array(buffer)[0] === 256;
})();

Reference:

DataView:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/DataView ArrayBuffer:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBuffer Typed Array Specification:http://www.khronos.org/registry/typedarray/specs/latest/