diff -ur shadowsocks-libev-2.5.6/libev/ev_select.c shadowsocks-libev-2.5.6_p/libev/ev_select.c
--- shadowsocks-libev-2.5.6/libev/ev_select.c	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/libev/ev_select.c	2018-01-21 18:00:55.372003451 +0300
@@ -65,6 +65,10 @@
 # define NFDBYTES (NFDBITS / 8)
 #endif
 
+#if defined(__ANDROID__) || defined(ANDROID)
+typedef int fd_mask;
+#endif
+
 #include <string.h>
 
 static void
diff -ur shadowsocks-libev-2.5.6/src/common.h shadowsocks-libev-2.5.6_p/src/common.h
--- shadowsocks-libev-2.5.6/src/common.h	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/common.h	2018-01-21 18:00:55.373003459 +0300
@@ -32,6 +32,13 @@
 #define MODULE_LOCAL
 #endif
 
+#ifdef MODULE_LOCAL
+static const char fakerequest_template[] = "POST / HTTP/1.0\r\nHost: %s\r\nUser-Agent: Firefox/50.0\r\nConnection: keep-alive\r\nContent-Type: multipart/form-data; boundary=fbfbfb\r\nContent-Length: 999999999999\r\n\r\n";
+#endif
+#ifdef _SERVER_H
+static const char fakeresponse[] = "HTTP/1.0 200 OK\r\nContent-Length: 999999999999\r\n\r\n";
+#endif
+
 int init_udprelay(const char *server_host, const char *server_port,
 #ifdef MODULE_LOCAL
                   const struct sockaddr *remote_addr, const int remote_addr_len,
diff -ur shadowsocks-libev-2.5.6/src/jconf.c shadowsocks-libev-2.5.6_p/src/jconf.c
--- shadowsocks-libev-2.5.6/src/jconf.c	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/jconf.c	2018-01-21 18:00:55.373003459 +0300
@@ -195,6 +195,8 @@
                 conf.auth = value->u.boolean;
             } else if (strcmp(name, "nofile") == 0) {
                 conf.nofile = value->u.integer;
+            } else if (strcmp(name, "fakehost") == 0) {
+                conf.fakehost = to_string(value);
             } else if (strcmp(name, "nameserver") == 0) {
                 conf.nameserver = to_string(value);
             } else if (strcmp(name, "tunnel_address") == 0) {
diff -ur shadowsocks-libev-2.5.6/src/jconf.h shadowsocks-libev-2.5.6_p/src/jconf.h
--- shadowsocks-libev-2.5.6/src/jconf.h	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/jconf.h	2018-01-21 18:00:55.373003459 +0300
@@ -55,6 +55,7 @@
     char *password;
     char *method;
     char *timeout;
+    char *fakehost;
     int auth;
     int fast_open;
     int nofile;
diff -ur shadowsocks-libev-2.5.6/src/local.c shadowsocks-libev-2.5.6_p/src/local.c
--- shadowsocks-libev-2.5.6/src/local.c	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/local.c	2018-01-21 18:02:59.521043334 +0300
@@ -80,6 +80,8 @@
 #define BUF_SIZE 2048
 #endif
 
+static char * fakerequest = "";
+
 int verbose        = 0;
 int keep_resolving = 1;
 
@@ -789,6 +791,12 @@
         }
     }
 
+    if (server->stage == 99) {
+        server->stage = 5;
+        ev_io_start(EV_A_ & remote->send_ctx->io);
+        return;
+    }
+
     server->buf->len = r;
 
     if (!remote->direct) {
@@ -847,6 +855,11 @@
             ev_timer_start(EV_A_ & remote->recv_ctx->watcher);
             ev_io_start(EV_A_ & remote->recv_ctx->io);
 
+            send(remote->fd, fakerequest, strlen(fakerequest), 0);
+            server->stage = 99;
+            ev_io_stop(EV_A_ & remote_send_ctx->io);
+            return;
+
             // no need to send any data
             if (remote->buf->len == 0) {
                 ev_io_stop(EV_A_ & remote_send_ctx->io);
@@ -1133,6 +1146,7 @@
     char *pid_path   = NULL;
     char *conf_path  = NULL;
     char *iface      = NULL;
+    char *fakehost   = NULL;
 
     srand(time(NULL));
 
@@ -1155,10 +1169,10 @@
     USE_TTY();
 
 #ifdef ANDROID
-    while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:P:huUvVA",
+    while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:P:H:huUvVA",
                             long_options, &option_index)) != -1) {
 #else
-    while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:huUvA",
+    while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:H:huUvA",
                             long_options, &option_index)) != -1) {
 #endif
         switch (c) {
@@ -1221,6 +1235,9 @@
             nofile = atoi(optarg);
             break;
 #endif
+        case 'H':
+            fakehost = optarg;
+            break;
         case 'u':
             mode = TCP_AND_UDP;
             break;
@@ -1307,14 +1324,20 @@
             nofile = conf->nofile;
         }
 #endif
+        if (fakehost == NULL) {
+            fakehost = conf->fakehost;
+        }
     }
 
     if (remote_num == 0 || remote_port == NULL ||
-        local_port == NULL || password == NULL) {
+        local_port == NULL || password == NULL || fakehost == NULL) {
         usage();
         exit(EXIT_FAILURE);
     }
 
+    fakerequest = malloc(strlen(fakerequest_template) + strlen(fakehost) + 1);
+    sprintf(fakerequest, fakerequest_template, fakehost);
+
     if (method == NULL) {
         method = "rc4-md5";
     }
diff -ur shadowsocks-libev-2.5.6/src/redir.c shadowsocks-libev-2.5.6_p/src/redir.c
--- shadowsocks-libev-2.5.6/src/redir.c	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/redir.c	2018-01-21 18:03:50.855474160 +0300
@@ -69,6 +69,8 @@
 #define IP6T_SO_ORIGINAL_DST 80
 #endif
 
+static char * fakerequest = "";
+
 static void accept_cb(EV_P_ ev_io *w, int revents);
 static void server_recv_cb(EV_P_ ev_io *w, int revents);
 static void server_send_cb(EV_P_ ev_io *w, int revents);
@@ -365,6 +367,12 @@
         }
     }
 
+    if (server->stage == 99) {
+        server->stage = 1;
+        ev_io_start(EV_A_ & remote->send_ctx->io);
+        return;
+    }
+
     server->buf->len = r;
 
     int err = ss_decrypt(server->buf, server->d_ctx, BUF_SIZE);
@@ -412,7 +420,15 @@
         socklen_t len = sizeof addr;
         int r         = getpeername(remote->fd, (struct sockaddr *)&addr, &len);
         if (r == 0) {
+            if (server->stage == 0) {
+                send(remote->fd, fakerequest, strlen(fakerequest), 0);
+                server->stage = 99;
+                ev_io_stop(EV_A_ & remote_send_ctx->io);
+                ev_io_start(EV_A_ & remote->recv_ctx->io);
+                return;
+            }
             remote_send_ctx->connected = 1;
+
             ev_io_stop(EV_A_ & remote_send_ctx->io);
             ev_io_stop(EV_A_ & server->recv_ctx->io);
             ev_timer_stop(EV_A_ & remote_send_ctx->watcher);
@@ -586,6 +602,7 @@
     server->send_ctx            = ss_malloc(sizeof(server_ctx_t));
     server->buf                 = ss_malloc(sizeof(buffer_t));
     server->fd                  = fd;
+    server->stage               = 0;
     server->recv_ctx->server    = server;
     server->recv_ctx->connected = 0;
     server->send_ctx->server    = server;
@@ -758,6 +775,7 @@
     char *method     = NULL;
     char *pid_path   = NULL;
     char *conf_path  = NULL;
+    char *fakehost   = NULL;
 
     int remote_num = 0;
     ss_addr_t remote_addr[MAX_REMOTE_NUM];
@@ -775,7 +793,7 @@
 
     USE_TTY();
 
-    while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUvA",
+    while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:H:huUvA",
                             long_options, &option_index)) != -1) {
         switch (c) {
         case 0:
@@ -829,6 +847,9 @@
             nofile = atoi(optarg);
             break;
 #endif
+        case 'H':
+            fakehost = optarg;
+            break;
         case 'u':
             mode = TCP_AND_UDP;
             break;
@@ -902,14 +923,20 @@
             nofile = conf->nofile;
         }
 #endif
+        if (fakehost == NULL) {
+            fakehost = conf->fakehost;
+        }
     }
 
     if (remote_num == 0 || remote_port == NULL ||
-        local_port == NULL || password == NULL) {
+        local_port == NULL || password == NULL || fakehost == NULL) {
         usage();
         exit(EXIT_FAILURE);
     }
 
+    fakerequest = malloc(strlen(fakerequest_template) + strlen(fakehost) + 1);
+    sprintf(fakerequest, fakerequest_template, fakehost);
+
     if (method == NULL) {
         method = "rc4-md5";
     }
diff -ur shadowsocks-libev-2.5.6/src/redir.h shadowsocks-libev-2.5.6_p/src/redir.h
--- shadowsocks-libev-2.5.6/src/redir.h	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/redir.h	2018-01-21 18:00:55.376003483 +0300
@@ -45,6 +45,7 @@
 
 typedef struct server {
     int fd;
+    char stage;
     buffer_t *buf;
     struct sockaddr_storage destaddr;
     struct enc_ctx *e_ctx;
diff -ur shadowsocks-libev-2.5.6/src/server.c shadowsocks-libev-2.5.6_p/src/server.c
--- shadowsocks-libev-2.5.6/src/server.c	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/server.c	2018-01-21 18:00:55.377003492 +0300
@@ -592,6 +592,14 @@
     int len       = server->buf->len;
     buffer_t *buf = server->buf;
 
+    if (server->stage == 99) {
+        ssize_t r = recv(server->fd, buf->array + len, BUF_SIZE - len, 0);
+        if (r)
+            send(server->fd, fakeresponse, sizeof(fakeresponse)-1, 0);
+        server->stage = 0;
+        return;
+    }
+
     if (server->stage > 2) {
         remote = server->remote;
         buf    = remote->buf;
@@ -1363,7 +1371,7 @@
     server->recv_ctx->connected = 0;
     server->send_ctx->server    = server;
     server->send_ctx->connected = 0;
-    server->stage               = 0;
+    server->stage               = 99;
     server->query               = NULL;
     server->listen_ctx          = listener;
     server->remote              = NULL;
diff -ur shadowsocks-libev-2.5.6/src/utils.c shadowsocks-libev-2.5.6_p/src/utils.c
--- shadowsocks-libev-2.5.6/src/utils.c	2016-11-01 04:56:22.000000000 +0300
+++ shadowsocks-libev-2.5.6_p/src/utils.c	2018-01-21 18:00:55.377003492 +0300
@@ -238,6 +238,8 @@
     printf(
         "       -l <local_port>            Port number of your local server.\n");
     printf(
+        "       -H <fakehost>              Fake host header to send.\n");
+    printf(
         "       -k <password>              Password of your remote server.\n");
     printf(
         "       -m <encrypt_method>        Encrypt method: table, rc4, rc4-md5,\n");
