Add mptcp option, close #756

This commit is contained in:
Max Lv
2016-08-04 13:30:39 +08:00
parent b1f5c68650
commit d319c0300c
16 changed files with 160 additions and 40 deletions
+5
View File
@@ -105,6 +105,11 @@ Enable ACL (Access Control List) and specify config file.
--mtu <MTU>::
Specify the MTU of your network interface.
--mptcp::
Enable Multipath TCP.
+
Only available with MPTCP enabled Linux kernel.
-v::
Enable verbose mode.
+5
View File
@@ -92,6 +92,11 @@ Enable onetime authentication.
--mtu <MTU>::
Specify the MTU of your network interface.
--mptcp::
Enable Multipath TCP.
+
Only available with MPTCP enabled Linux kernel.
-v::
Enable verbose mode.
+5
View File
@@ -118,6 +118,11 @@ Only available in server and manager mode.
--mtu <MTU>::
Specify the MTU of your network interface.
--mptcp::
Enable Multipath TCP.
+
Only available with MPTCP enabled Linux kernel.
-v::
Enable verbose mode.
+5
View File
@@ -103,6 +103,11 @@ Only used and available in tunnel mode.
--mtu <MTU>::
Specify the MTU of your network interface.
--mptcp::
Enable Multipath TCP.
+
Only available with MPTCP enabled Linux kernel.
-v::
Enable verbose mode.
+6
View File
@@ -99,6 +99,8 @@ jconf_t *read_jconf(const char *file)
{
static jconf_t conf;
memset(&conf, 0, sizeof(jconf_t));
char *buf;
json_value *obj;
@@ -206,6 +208,10 @@ jconf_t *read_jconf(const char *file)
LOGI("ignore unknown mode: %s, use tcp_only as fallback",
mode_str);
free(mode_str);
} else if (strcmp(name, "mtu") == 0) {
conf.mtu = value->u.integer;
} else if (strcmp(name, "mptcp") == 0) {
conf.mptcp = value->u.boolean;
}
}
} else {
+2 -1
View File
@@ -33,7 +33,6 @@
#define TCP_AND_UDP 1
#define UDP_ONLY 3
typedef struct {
char *host;
char *port;
@@ -61,6 +60,8 @@ typedef struct {
char *nameserver;
char *tunnel_address;
int mode;
int mtu;
int mptcp;
} jconf_t;
jconf_t *read_jconf(const char *file);
+33 -10
View File
@@ -218,7 +218,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -280,7 +280,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
// connecting, wait until connected
int r = connect(remote->fd, (struct sockaddr *)&(remote->addr), remote->addr_len);
if (r < 0 && errno != CONNECT_IN_PROGRESS) {
if (r == -1 && errno != CONNECT_IN_PROGRESS) {
ERROR("connect");
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
@@ -587,7 +587,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(server->fd, server->buf->array + server->buf->idx,
server->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("server_send_cb_send");
close_and_free_remote(EV_A_ remote);
@@ -656,7 +656,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -750,7 +750,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx,
remote->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("remote_send_cb_send");
// close and free
@@ -911,7 +911,7 @@ static remote_t *create_remote(listen_ctx_t *listener,
int remotefd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (remotefd < 0) {
if (remotefd == -1) {
ERROR("socket");
return NULL;
}
@@ -922,6 +922,13 @@ static remote_t *create_remote(listen_ctx_t *listener,
setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
if (listener->mptcp == 1) {
int err = setsockopt(remotefd, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt));
if (err == -1) {
ERROR("failed to enable multipath TCP");
}
}
// Setup
setnonblocking(remotefd);
#ifdef SET_INTERFACE
@@ -982,7 +989,8 @@ int main(int argc, char **argv)
{
int i, c;
int pid_flags = 0;
int mtu = 0;
int mtu = 0;
int mptcp = 0;
char *user = NULL;
char *local_port = NULL;
char *local_addr = NULL;
@@ -1004,6 +1012,7 @@ int main(int argc, char **argv)
{ "fast-open", no_argument , 0, 0 },
{ "acl" , required_argument, 0, 0 },
{ "mtu" , required_argument, 0, 0 },
{ "mptcp" , no_argument , 0, 0 },
{ "help" , no_argument , 0, 0 },
{ 0, 0, 0, 0 }
};
@@ -1028,8 +1037,11 @@ int main(int argc, char **argv)
acl = !init_acl(optarg, BLACK_LIST);
} else if (option_index == 2) {
mtu = atoi(optarg);
LOGI("Set MTU to %d", mtu);
LOGI("set MTU to %d", mtu);
} else if (option_index == 3) {
mptcp = 1;
LOGI("enable multipath TCP");
} else if (option_index == 4) {
usage();
exit(EXIT_SUCCESS);
}
@@ -1150,6 +1162,12 @@ int main(int argc, char **argv)
if (mode == TCP_ONLY) {
mode = conf->mode;
}
if (mtu == 0) {
mtu = conf->mtu;
}
if (mptcp == 0) {
mptcp = conf->mptcp;
}
#ifdef HAVE_SETRLIMIT
if (nofile == 0) {
nofile = conf->nofile;
@@ -1230,6 +1248,7 @@ int main(int argc, char **argv)
listen_ctx.timeout = atoi(timeout);
listen_ctx.iface = iface;
listen_ctx.method = m;
listen_ctx.mptcp = mptcp;
// Setup signal handler
struct ev_signal sigint_watcher;
@@ -1245,7 +1264,7 @@ int main(int argc, char **argv)
// Setup socket
int listenfd;
listenfd = create_and_bind(local_addr, local_port);
if (listenfd < 0) {
if (listenfd == -1) {
FATAL("bind() error");
}
if (listen(listenfd, SOMAXCONN) == -1) {
@@ -1324,11 +1343,14 @@ int start_ss_local_server(profile_t profile)
int local_port = profile.local_port;
int timeout = profile.timeout;
int mtu = 0;
int mptcp = 0;
auth = profile.auth;
mode = profile.mode;
fast_open = profile.fast_open;
verbose = profile.verbose;
mtu = profile.mtu;
mptcp = profile.mptcp;
char local_port_str[16];
char remote_port_str[16];
@@ -1385,13 +1407,14 @@ int start_ss_local_server(profile_t profile)
listen_ctx.timeout = timeout;
listen_ctx.method = m;
listen_ctx.iface = NULL;
listen_ctx.mptcp = mptcp;
if (mode != UDP_ONLY) {
// Setup socket
int listenfd;
listenfd = create_and_bind(local_addr, local_port_str);
if (listenfd < 0) {
if (listenfd == -1) {
ERROR("bind()");
return -1;
}
+1
View File
@@ -38,6 +38,7 @@ typedef struct listen_ctx {
int method;
int timeout;
int fd;
int mptcp;
struct sockaddr **remote_addr;
} listen_ctx_t;
+5
View File
@@ -23,6 +23,11 @@
#ifndef _NETUTILS_H
#define _NETUTILS_H
/* Define the flag MPTCP_ENABLED if not defined*/
#ifndef MPTCP_ENABLED
#define MPTCP_ENABLED 26
#endif
/** byte size of ip4 address */
#define INET_SIZE 4
/** byte size of ip6 address */
+33 -12
View File
@@ -181,7 +181,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -273,7 +273,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(server->fd, server->buf->array + server->buf->idx,
server->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("send");
close_and_free_remote(EV_A_ remote);
@@ -321,7 +321,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -451,7 +451,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx,
remote->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("send");
// close and free
@@ -622,11 +622,12 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
struct sockaddr *remote_addr = listener->remote_addr[index];
int remotefd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (remotefd < 0) {
if (remotefd == -1) {
ERROR("socket");
return;
}
// Set flags
setsockopt(remotefd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
@@ -642,9 +643,17 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(remotefd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(remotefd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
// Setup
// Set non blocking
setnonblocking(remotefd);
// Enable MPTCP
if (listener->mptcp == 1) {
int err = setsockopt(remotefd, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt));
if (err == -1) {
ERROR("failed to enable multipath TCP");
}
}
server_t *server = new_server(serverfd, listener->method);
remote_t *remote = new_remote(remotefd, listener->timeout);
server->remote = remote;
@@ -653,7 +662,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
int r = connect(remotefd, remote_addr, get_sockaddr_len(remote_addr));
if (r < 0 && errno != CONNECT_IN_PROGRESS) {
if (r == -1 && errno != CONNECT_IN_PROGRESS) {
ERROR("connect");
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
@@ -683,6 +692,7 @@ int main(int argc, char **argv)
int i, c;
int pid_flags = 0;
int mptcp = 0;
int mtu = 0;
char *user = NULL;
char *local_port = NULL;
@@ -699,9 +709,10 @@ int main(int argc, char **argv)
int option_index = 0;
static struct option long_options[] = {
{ "mtu", required_argument, 0, 0 },
{ "help", no_argument , 0, 0 },
{ 0, 0 , 0, 0 }
{ "mtu", required_argument, 0, 0 },
{ "mptcp", no_argument , 0, 0 },
{ "help", no_argument , 0, 0 },
{ 0, 0 , 0, 0 }
};
opterr = 0;
@@ -712,8 +723,11 @@ int main(int argc, char **argv)
case 0:
if (option_index == 0) {
mtu = atoi(optarg);
LOGI("Set MTU to %d", mtu);
LOGI("set MTU to %d", mtu);
} else if (option_index == 1) {
mptcp = 1;
LOGI("enable multipath TCP");
} else if (option_index == 2) {
usage();
exit(EXIT_SUCCESS);
}
@@ -818,6 +832,12 @@ int main(int argc, char **argv)
if (auth == 0) {
auth = conf->auth;
}
if (mtu == 0) {
mtu = conf->mtu;
}
if (mptcp == 0) {
mptcp = conf->mptcp;
}
#ifdef HAVE_SETRLIMIT
if (nofile == 0) {
nofile = conf->nofile;
@@ -885,6 +905,7 @@ int main(int argc, char **argv)
}
listen_ctx.timeout = atoi(timeout);
listen_ctx.method = m;
listen_ctx.mptcp = mptcp;
struct ev_loop *loop = EV_DEFAULT;
@@ -892,7 +913,7 @@ int main(int argc, char **argv)
// Setup socket
int listenfd;
listenfd = create_and_bind(local_addr, local_port);
if (listenfd < 0) {
if (listenfd == -1) {
FATAL("bind() error");
}
if (listen(listenfd, SOMAXCONN) == -1) {
+1
View File
@@ -33,6 +33,7 @@ typedef struct listen_ctx {
int timeout;
int fd;
int method;
int mptcp;
struct sockaddr **remote_addr;
} listen_ctx_t;
+26 -8
View File
@@ -303,7 +303,7 @@ int setnonblocking(int fd)
#endif
int create_and_bind(const char *host, const char *port)
int create_and_bind(const char *host, const char *port, int mptcp)
{
struct addrinfo hints;
struct addrinfo *result, *rp, *ipv4v6bindall;
@@ -372,6 +372,13 @@ int create_and_bind(const char *host, const char *port)
LOGI("port reuse enabled");
}
if (mptcp == 1) {
int err = setsockopt(listen_sock, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt));
if (err == -1) {
ERROR("failed to enable multipath TCP");
}
}
s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen);
if (s == 0) {
/* We managed to bind successfully! */
@@ -404,7 +411,7 @@ static remote_t *connect_to_remote(struct addrinfo *res,
// initialize remote socks
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0) {
if (sockfd == -1) {
ERROR("socket");
close(sockfd);
return NULL;
@@ -484,7 +491,7 @@ static remote_t *connect_to_remote(struct addrinfo *res,
if (!fast_open) {
int r = connect(sockfd, res->ai_addr, res->ai_addrlen);
if (r < 0 && errno != CONNECT_IN_PROGRESS) {
if (r == -1 && errno != CONNECT_IN_PROGRESS) {
ERROR("connect");
close(sockfd);
return NULL;
@@ -859,7 +866,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(server->fd, server->buf->array + server->buf->idx,
server->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("server_send_send");
close_and_free_remote(EV_A_ remote);
@@ -995,7 +1002,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -1338,6 +1345,7 @@ int main(int argc, char **argv)
{
int i, c;
int pid_flags = 0;
int mptcp = 0;
int mtu = 0;
char *user = NULL;
char *password = NULL;
@@ -1360,6 +1368,7 @@ int main(int argc, char **argv)
{ "acl" , required_argument, 0, 0 },
{ "manager-address", required_argument, 0, 0 },
{ "mtu" , required_argument, 0, 0 },
{ "mptcp" , no_argument , 0, 0 },
{ "help" , no_argument , 0, 0 },
{ 0, 0, 0, 0 }
};
@@ -1382,8 +1391,11 @@ int main(int argc, char **argv)
manager_address = optarg;
} else if (option_index == 3) {
mtu = atoi(optarg);
LOGI("Set MTU to %d", mtu);
LOGI("set MTU to %d", mtu);
} else if (option_index == 4) {
mptcp = 1;
LOGI("enable multipath TCP");
} else if (option_index == 5) {
usage();
exit(EXIT_SUCCESS);
}
@@ -1497,6 +1509,12 @@ int main(int argc, char **argv)
if (mode == TCP_ONLY) {
mode = conf->mode;
}
if (mtu == 0) {
mtu = conf->mtu;
}
if (mptcp == 0) {
mptcp = conf->mptcp;
}
#ifdef TCP_FASTOPEN
if (fast_open == 0) {
fast_open = conf->fast_open;
@@ -1617,8 +1635,8 @@ int main(int argc, char **argv)
if (mode != UDP_ONLY) {
// Bind to port
int listenfd;
listenfd = create_and_bind(host, server_port);
if (listenfd < 0) {
listenfd = create_and_bind(host, server_port, mptcp);
if (listenfd == -1) {
FATAL("bind() error");
}
if (listen(listenfd, SSMAXCONN) == -1) {
+2
View File
@@ -38,6 +38,8 @@ typedef struct {
int fast_open; // enable tcp fast open
int mode; // enable udp relay
int auth; // enable one-time authentication
int mtu; // MTU of interface
int mptcp; // enable multipath TCP
int verbose; // verbose mode
} profile_t;
+28 -9
View File
@@ -183,7 +183,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -249,7 +249,7 @@ static void server_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(server->fd, server->buf->array + server->buf->idx,
server->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("send");
close_and_free_remote(EV_A_ remote);
@@ -307,7 +307,7 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
} else if (r < 0) {
} else if (r == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// no data
// continue to wait for recv
@@ -465,7 +465,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents)
// has data to send
ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx,
remote->buf->len, 0);
if (s < 0) {
if (s == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ERROR("send");
// close and free
@@ -627,7 +627,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
struct sockaddr *remote_addr = listener->remote_addr[index];
int remotefd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (remotefd < 0) {
if (remotefd == -1) {
ERROR("socket");
return;
}
@@ -647,6 +647,13 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
if (listener->mptcp == 1) {
int err = setsockopt(remotefd, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt));
if (err == -1) {
ERROR("failed to enable multipath TCP");
}
}
// Setup
setnonblocking(remotefd);
#ifdef SET_INTERFACE
@@ -664,7 +671,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
int r = connect(remotefd, remote_addr, get_sockaddr_len(remote_addr));
if (r < 0 && errno != CONNECT_IN_PROGRESS) {
if (r == -1 && errno != CONNECT_IN_PROGRESS) {
ERROR("connect");
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
@@ -692,7 +699,8 @@ int main(int argc, char **argv)
int i, c;
int pid_flags = 0;
int mtu = 0;
int mptcp = 0;
int mtu = 0;
char *user = NULL;
char *local_port = NULL;
char *local_addr = NULL;
@@ -713,6 +721,7 @@ int main(int argc, char **argv)
int option_index = 0;
static struct option long_options[] = {
{ "mtu", required_argument, 0, 0 },
{ "mptcp",no_argument, 0, 0 },
{ "help", no_argument, 0, 0 },
{ 0, 0, 0, 0 }
};
@@ -732,8 +741,11 @@ int main(int argc, char **argv)
case 0:
if (option_index == 0) {
mtu = atoi(optarg);
LOGI("Set MTU to %d", mtu);
LOGI("set MTU to %d", mtu);
} else if (option_index == 1) {
mptcp = 1;
LOGI("enable multipath TCP");
} else if (option_index == 2) {
usage();
exit(EXIT_SUCCESS);
}
@@ -858,6 +870,12 @@ int main(int argc, char **argv)
if (mode == TCP_ONLY) {
mode = conf->mode;
}
if (mtu == 0) {
mtu = conf->mtu;
}
if (mptcp == 0) {
mptcp = conf->mptcp;
}
#ifdef HAVE_SETRLIMIT
if (nofile == 0) {
nofile = conf->nofile;
@@ -938,6 +956,7 @@ int main(int argc, char **argv)
listen_ctx.timeout = atoi(timeout);
listen_ctx.iface = iface;
listen_ctx.method = m;
listen_ctx.mptcp = mptcp;
struct ev_loop *loop = EV_DEFAULT;
@@ -945,7 +964,7 @@ int main(int argc, char **argv)
// Setup socket
int listenfd;
listenfd = create_and_bind(local_addr, local_port);
if (listenfd < 0) {
if (listenfd == -1) {
FATAL("bind() error:");
}
if (listen(listenfd, SOMAXCONN) == -1) {
+1
View File
@@ -37,6 +37,7 @@ typedef struct listen_ctx {
int method;
int timeout;
int fd;
int mptcp;
struct sockaddr **remote_addr;
} listen_ctx_t;
+2
View File
@@ -311,6 +311,8 @@ void usage()
#endif
printf(
" [--mtu <MTU>] MTU of your network interface.\n");
printf(
" [--mptcp] Enable Multipath TCP on MPTCP Kernel.\n");
printf("\n");
printf(
" [-v] Verbose mode.\n");