How Peerplug works

This document explains how Peerplug interfaces with it’s host application and how it intercepts it’s traffic. This will give you a general idea on how Peerplug works.

For gurus: Please note, some aspects are oversimplified to save your valuable time. For example, the document claims that okhttp library on Android does system calls. We skip the part of okhttp -> jni -> libc(bionic) -> system_call as it’s irrelevant for this document.

Preparation

It is recommended for the reader to be familiar with the following concepts:

App/OS/Hardware architecture

We will take Youtube as an example app, Android as an example OS and Google Pixel as an example phone. Let’s see the general architecture:

Youtube is an app that runs on top of the Android Operating System. Android itself is running on top of the Pixel device which is a Hardware device.

The above image is less illustrating the practical inter-layer communication of the components so let’s look at it this way:

In order to communicate, Youtube uses “system calls” to talk to the Android OS.

Android OS communicates with the hardware as to do the physical communication.

HTTP Requests

Now let’s see how an app downloads something from the Internet. For example how simple “HTTP GET” is done, this is what happens when your app has something like okhttp.get(“http://example.com/file.dat”) somewhere at the high level of your app.

The “okhttp” library prepares two buffers:

  1. “http_request” buffer which contains the request
  2. “http_reply” buffer which will contain the reply (let’s assume the size is known in advance for the sake of simplicity)

After that okhttp library translates your request to system calls, which are:

  1. socket() – Create a TCP socket.
  2. connect(socket s, destination d) – Make a TCP connection on a socket s to destination d.
  3. send(socket s, buffer http_request) – Send the “GET” request to the remote server from the “http_request” buffer.
  4. recv(socket s, buffer http_reply) – Receive the reply from the web server and write it to the http_reply buffer.
  5. close(socket s) – Close the connection.

Now the “http_reply” contains the data that can be parsed to a high level http object.

Quick question: What happens if you ask to download the same resource twice ?

Quick answer: You will practically download the same resource twice wasting 50% of the traffic if the actual file doesn’t change over time.

Adding Peerplug to the picture

With Peerplug your app doesn’t call any real system calls of the operating system regarding anything that is networking related. Instead it seamlessly talks to Peerplug. Peerplug then sends those “system calls” to the operating system if necessary.

Peerplug achieves this by intercepting the system calls using method swizzling(a.k.a Monkey Patch) technique.

Let’s now get back to our okhttp.get(“http://example.com/file.dat”) example and see what will happen now. In addition, we will see what Peerplug does while tracing this download.

For each system_call() function, we will assume your application calls Peerplug pp_system_call() function due to method swizzling described earlier.

  1. pp_socket() – Peerplug calls socket() and remembers that the returned socket s is a TCP socket and it should be tracked.
  2. pp_connect(socket s, destination d) – Peerplug is tracking “s” and therefore adds information that it is now connected to the destination “d” then calls connect() system call.
  3. pp_send(socket s, buffer http_request) – Peerplug analyzes the request in “http_request” buffer and finds out that it’s a request for “http://example.com/file.dat”. Peerplug has no knowledge about this resource so he passes the system call “as is” to send();
  4. pp_recv(socket s, buffer http_reply) – Peerplug calls the original recv() then analyzes the reply. Peerplug finds the reply and caches the reply for “http://example.com/file.dat” in it’s cache.
  5. pp_close(socket s) – Peerplug calls close() and stops tracking socket s.

Now Peerplug has the cache for “http://example.com/file.dat”. Now if you will try to download this file again, you will not actually download it but get it from Peerplug cache.

Let’s assume your app does okhttp.get(“http://example.com/file.dat”) again.

  1. pp_socket() – Peerplug calls socket() and remembers that the returned socket s is a TCP socket and it should be tracked.
  2. pp_connnect(socket s, destination d) – Peerplug is tracking “s” and therefore adds information that it is now connected to the destination “d” then calls connect() system call.
  3. pp_send(socket s, buffer http_request) – Peerplug analyzes the request in “http_request” buffer and finds out that it’s a request for “http://example.com/file.dat”. Peerplug has this resource in it’s cache and therefore it will not pass the system call. It will return and “swallow” the system call to simulate like it has been called. Peerplug will mark “s” as one that should receive reply for that resource.
  4. pp_recv(socket s, buffer http_reply) – “s” is marked as one that should get reply for the cached resource. Peerplug will copy the cached resource “http://example.com/file.dat” to “http_reply” and return simulating a call to real recv().
  5. pp_close(socket s) – Peerplug calls close() and stops tracking socket s.

As you can see, the second call did not actually transfer any data. Moreover, advanced Peerplug configuration can allow Peerplug AI to even save the “connect()” syscall and make the request work even if Internet is unavailable during the request.

Host application has no knowledge that it was actually “tricked” and the reply was provided from a cache instead of the remote server.

Of course this limited example just barely scratches the surface and doesn’t demonstrate how Peerplug actually achieves acceleration and offloads the traffic but it provides a general idea on how it interfaces with the host application.

To understand how Peerplug actually achieves MESH acceleration, please read How Peerplug accelerates document.