mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-29 12:36:53 +00:00
Re-add support for MinGW
This commit is contained in:
+15
-1
@@ -66,7 +66,7 @@ dnl Add library for mingw
|
||||
case $host in
|
||||
*-mingw*)
|
||||
CFLAGS="$CFLAGS -mno-ms-bitfields"
|
||||
LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -lcrypt32"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
;;
|
||||
*-cygwin*)
|
||||
CFLAGS="$CFLAGS -mno-ms-bitfields"
|
||||
@@ -93,6 +93,10 @@ case $host in
|
||||
os_support=linux
|
||||
AC_MSG_RESULT(Linux)
|
||||
;;
|
||||
*-mingw*)
|
||||
os_support=mingw
|
||||
AC_MSG_RESULT(MinGW)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(transparent proxy does not support for $host)
|
||||
;;
|
||||
@@ -161,6 +165,10 @@ AC_CHECK_HEADERS([net/if.h], [], [],
|
||||
])
|
||||
|
||||
case $host in
|
||||
*-mingw*)
|
||||
AC_DEFINE([CONNECT_IN_PROGRESS], [WSAEWOULDBLOCK], [errno for incomplete non-blocking connect(2)])
|
||||
AC_CHECK_HEADERS([winsock2.h ws2tcpip.h], [], [AC_MSG_ERROR([Missing MinGW headers])], [])
|
||||
;;
|
||||
*-linux*)
|
||||
AC_DEFINE([CONNECT_IN_PROGRESS], [EINPROGRESS], [errno for incomplete non-blocking connect(2)])
|
||||
dnl Checks for netfilter headers
|
||||
@@ -219,6 +227,12 @@ AC_CHECK_LIB(socket, connect)
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([malloc memset posix_memalign socket])
|
||||
|
||||
AC_ARG_WITH(ev,
|
||||
AS_HELP_STRING([--with-ev=DIR], [use a specific libev library]),
|
||||
[CFLAGS="$CFLAGS -I$withval/include"
|
||||
CPPFLAGS="$CPPFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"]
|
||||
)
|
||||
AC_CHECK_HEADERS([ev.h libev/ev.h], [], [])
|
||||
AC_CHECK_LIB([ev], [ev_loop_destroy], [LIBS="-lev $LIBS"], [AC_MSG_ERROR([Couldn't find libev. Try installing libev-dev@<:@el@:>@.])])
|
||||
|
||||
|
||||
+22
-23
@@ -19,7 +19,10 @@ SS_COMMON_LIBS += -lbloom -lcork -lcorkipset
|
||||
endif
|
||||
SS_COMMON_LIBS += -lev -lsodium -lm
|
||||
|
||||
bin_PROGRAMS = ss-local ss-tunnel ss-server ss-manager
|
||||
bin_PROGRAMS = ss-local ss-tunnel ss-server
|
||||
if !BUILD_WINCOMPAT
|
||||
bin_PROGRAMS += ss-manager
|
||||
endif
|
||||
|
||||
sni_src = http.c \
|
||||
tls.c
|
||||
@@ -30,41 +33,37 @@ acl_src = rule.c \
|
||||
crypto_src = crypto.c \
|
||||
aead.c \
|
||||
stream.c \
|
||||
ppbloom.c \
|
||||
ppbloom.c \
|
||||
base64.c
|
||||
|
||||
plugin_src = plugin.c
|
||||
|
||||
ss_local_SOURCES = utils.c \
|
||||
jconf.c \
|
||||
json.c \
|
||||
udprelay.c \
|
||||
cache.c \
|
||||
netutils.c \
|
||||
local.c \
|
||||
common_src = utils.c \
|
||||
jconf.c \
|
||||
json.c \
|
||||
udprelay.c \
|
||||
cache.c \
|
||||
netutils.c
|
||||
|
||||
if BUILD_WINCOMPAT
|
||||
common_src += winsock.c
|
||||
endif
|
||||
|
||||
ss_local_SOURCES = local.c \
|
||||
$(common_src) \
|
||||
$(crypto_src) \
|
||||
$(plugin_src) \
|
||||
$(sni_src) \
|
||||
$(acl_src)
|
||||
|
||||
ss_tunnel_SOURCES = utils.c \
|
||||
jconf.c \
|
||||
json.c \
|
||||
udprelay.c \
|
||||
cache.c \
|
||||
netutils.c \
|
||||
tunnel.c \
|
||||
ss_tunnel_SOURCES = tunnel.c \
|
||||
$(common_src) \
|
||||
$(crypto_src) \
|
||||
$(plugin_src)
|
||||
|
||||
ss_server_SOURCES = utils.c \
|
||||
netutils.c \
|
||||
jconf.c \
|
||||
json.c \
|
||||
udprelay.c \
|
||||
cache.c \
|
||||
resolv.c \
|
||||
ss_server_SOURCES = resolv.c \
|
||||
server.c \
|
||||
$(common_src) \
|
||||
$(crypto_src) \
|
||||
$(plugin_src) \
|
||||
$(sni_src) \
|
||||
|
||||
@@ -31,11 +31,14 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <sodium.h>
|
||||
#ifndef __MINGW32__
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "ppbloom.h"
|
||||
#include "aead.h"
|
||||
#include "utils.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#define NONE (-1)
|
||||
#define AES128GCM 0
|
||||
|
||||
+1
-1
@@ -372,7 +372,7 @@ crypto_parse_key(const char *base64, uint8_t *key, size_t key_len)
|
||||
rand_bytes(key, key_len);
|
||||
base64_encode(out_key, out_len, key, key_len);
|
||||
LOGE("Invalid key for your chosen cipher!");
|
||||
LOGE("It requires a %zu-byte key encoded with URL-safe Base64", key_len);
|
||||
LOGE("It requires a " SIZE_FMT "-byte key encoded with URL-safe Base64", key_len);
|
||||
LOGE("Generating a new random key: %s", out_key);
|
||||
FATAL("Please use the key above or input a valid key");
|
||||
return key_len;
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#ifndef _CRYPTO_H
|
||||
#define _CRYPTO_H
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
+7
-1
@@ -35,6 +35,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define CONV_PTR (uintptr_t)
|
||||
#else
|
||||
#define CONV_PTR (unsigned long)
|
||||
#endif
|
||||
|
||||
const struct _json_value json_value_none;
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -138,7 +144,7 @@ static int new_value (json_state * state,
|
||||
values_size = sizeof (*value->u.object.values) * value->u.object.length;
|
||||
|
||||
if (! (value->u.object.values = (json_object_entry *) json_alloc
|
||||
(state, values_size + ((unsigned long) value->u.object.values), 0)) )
|
||||
(state, values_size + (CONV_PTR value->u.object.values), 0)) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
+47
-2
@@ -33,12 +33,12 @@
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#endif
|
||||
#ifdef LIB_ONLY
|
||||
#include "shadowsocks.h"
|
||||
#endif
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "tls.h"
|
||||
#include "plugin.h"
|
||||
#include "local.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#ifndef LIB_ONLY
|
||||
#ifdef __APPLE__
|
||||
@@ -104,8 +105,10 @@ static int udp_fd = 0;
|
||||
|
||||
static struct ev_signal sigint_watcher;
|
||||
static struct ev_signal sigterm_watcher;
|
||||
#ifndef __MINGW32__
|
||||
static struct ev_signal sigchld_watcher;
|
||||
static struct ev_signal sigusr1_watcher;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
#ifndef LIB_ONLY
|
||||
@@ -135,6 +138,7 @@ static server_t *new_server(int fd);
|
||||
|
||||
static struct cork_dllist connections;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
int
|
||||
setnonblocking(int fd)
|
||||
{
|
||||
@@ -144,6 +148,7 @@ setnonblocking(int fd)
|
||||
}
|
||||
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
create_and_bind(const char *addr, const char *port)
|
||||
@@ -1213,18 +1218,22 @@ signal_cb(EV_P_ ev_signal *w, int revents)
|
||||
{
|
||||
if (revents & EV_SIGNAL) {
|
||||
switch (w->signum) {
|
||||
#ifndef __MINGW32__
|
||||
case SIGCHLD:
|
||||
if (!is_plugin_running())
|
||||
LOGE("plugin service exit unexpectedly");
|
||||
else
|
||||
return;
|
||||
case SIGUSR1:
|
||||
#endif
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_stop(EV_DEFAULT, &sigchld_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigusr1_watcher);
|
||||
#endif
|
||||
keep_resolving = 0;
|
||||
ev_unloop(EV_A_ EVUNLOOP_ALL);
|
||||
}
|
||||
@@ -1276,7 +1285,9 @@ main(int argc, char **argv)
|
||||
char *plugin_opts = NULL;
|
||||
char *plugin_host = NULL;
|
||||
char *plugin_port = NULL;
|
||||
#ifndef __MINGW32__
|
||||
char tmp_port[8];
|
||||
#endif
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
@@ -1501,7 +1512,12 @@ main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#endif
|
||||
|
||||
if (plugin != NULL) {
|
||||
#ifndef __MINGW32__
|
||||
uint16_t port = get_local_port();
|
||||
if (port == 0) {
|
||||
FATAL("failed to find a free port");
|
||||
@@ -1511,6 +1527,9 @@ main(int argc, char **argv)
|
||||
plugin_port = tmp_port;
|
||||
|
||||
LOGI("plugin \"%s\" enabled", plugin);
|
||||
#else
|
||||
FATAL("plugins not implemented in MinGW port");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (method == NULL) {
|
||||
@@ -1560,6 +1579,7 @@ main(int argc, char **argv)
|
||||
LOGI("resolving hostname to IPv6 address first");
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (plugin != NULL) {
|
||||
int len = 0;
|
||||
size_t buf_size = 256 * remote_num;
|
||||
@@ -1577,10 +1597,13 @@ main(int argc, char **argv)
|
||||
FATAL("failed to start the plugin");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
// Setup keys
|
||||
LOGI("initializing ciphers... %s", method);
|
||||
@@ -1621,8 +1644,10 @@ main(int argc, char **argv)
|
||||
ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
|
||||
ev_signal_start(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_init(&sigchld_watcher, signal_cb, SIGCHLD);
|
||||
ev_signal_start(EV_DEFAULT, &sigchld_watcher);
|
||||
#endif
|
||||
|
||||
if (strcmp(local_addr, ":") > 0)
|
||||
LOGI("listening at [%s]:%s", local_addr, local_port);
|
||||
@@ -1674,6 +1699,7 @@ main(int argc, char **argv)
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// setuid
|
||||
if (user != NULL && !run_as(user)) {
|
||||
FATAL("failed to switch user");
|
||||
@@ -1682,6 +1708,7 @@ main(int argc, char **argv)
|
||||
if (geteuid() == 0) {
|
||||
LOGI("running from root user");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Init connections
|
||||
cork_dllist_init(&connections);
|
||||
@@ -1694,9 +1721,11 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
#ifndef __MINGW32__
|
||||
if (plugin != NULL) {
|
||||
stop_plugin();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mode != UDP_ONLY) {
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
@@ -1711,6 +1740,10 @@ main(int argc, char **argv)
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1743,6 +1776,10 @@ _start_ss_local_server(profile_t profile, ss_local_callback callback, void *udat
|
||||
sprintf(local_port_str, "%d", local_port);
|
||||
sprintf(remote_port_str, "%d", remote_port);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#endif
|
||||
|
||||
USE_LOGFILE(log);
|
||||
|
||||
if (profile.acl != NULL) {
|
||||
@@ -1753,18 +1790,22 @@ _start_ss_local_server(profile_t profile, ss_local_callback callback, void *udat
|
||||
local_addr = "127.0.0.1";
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
ev_signal_init(&sigint_watcher, signal_cb, SIGINT);
|
||||
ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
|
||||
ev_signal_start(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_init(&sigusr1_watcher, signal_cb, SIGUSR1);
|
||||
ev_signal_init(&sigchld_watcher, signal_cb, SIGCHLD);
|
||||
ev_signal_start(EV_DEFAULT, &sigusr1_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigchld_watcher);
|
||||
#endif
|
||||
|
||||
// Setup keys
|
||||
LOGI("initializing ciphers... %s", method);
|
||||
@@ -1848,6 +1889,10 @@ _start_ss_local_server(profile_t profile, ss_local_callback callback, void *udat
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__)
|
||||
#include <net/if.h>
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
#ifndef _NETUTILS_H
|
||||
#define _NETUTILS_H
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include "winsock.h"
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_TCP_H
|
||||
#include <linux/tcp.h>
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -299,3 +301,5 @@ is_plugin_running()
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+10
-3
@@ -32,13 +32,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#endif
|
||||
#include <ares.h>
|
||||
|
||||
#ifdef HAVE_LIBEV_EV_H
|
||||
@@ -52,6 +52,13 @@
|
||||
#include "resolv.h"
|
||||
#include "utils.h"
|
||||
#include "netutils.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define CONV_STATE_CB (ares_sock_state_cb)
|
||||
#else
|
||||
#define CONV_STATE_CB
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Implement DNS resolution interface using libc-ares
|
||||
@@ -147,7 +154,7 @@ resolv_init(struct ev_loop *loop, char *nameservers, int ipv6first)
|
||||
memset(&default_ctx, 0, sizeof(struct resolv_ctx));
|
||||
|
||||
default_ctx.options.sock_state_cb_data = &default_ctx;
|
||||
default_ctx.options.sock_state_cb = resolv_sock_state_cb;
|
||||
default_ctx.options.sock_state_cb = CONV_STATE_CB resolv_sock_state_cb;
|
||||
default_ctx.options.timeout = 3000;
|
||||
default_ctx.options.tries = 2;
|
||||
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#ifndef __MINGW32__
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
struct resolv_query;
|
||||
|
||||
|
||||
+44
-3
@@ -35,14 +35,14 @@
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#endif
|
||||
#include <libcork/core.h>
|
||||
|
||||
#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__)
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "acl.h"
|
||||
#include "plugin.h"
|
||||
#include "server.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
@@ -134,15 +135,20 @@ static char *manager_addr = NULL;
|
||||
uint64_t tx = 0;
|
||||
uint64_t rx = 0;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
ev_timer stat_update_watcher;
|
||||
#endif
|
||||
ev_timer block_list_watcher;
|
||||
|
||||
static struct ev_signal sigint_watcher;
|
||||
static struct ev_signal sigterm_watcher;
|
||||
#ifndef __MINGW32__
|
||||
static struct ev_signal sigchld_watcher;
|
||||
#endif
|
||||
|
||||
static struct cork_dllist connections;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
static void
|
||||
stat_update_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
{
|
||||
@@ -218,6 +224,7 @@ stat_update_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
|
||||
close(sfd);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
free_connections(struct ev_loop *loop)
|
||||
@@ -320,6 +327,7 @@ setfastopen(int fd)
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
int
|
||||
setnonblocking(int fd)
|
||||
{
|
||||
@@ -329,6 +337,7 @@ setnonblocking(int fd)
|
||||
}
|
||||
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
create_and_bind(const char *host, const char *port, int mptcp)
|
||||
@@ -1409,16 +1418,20 @@ signal_cb(EV_P_ ev_signal *w, int revents)
|
||||
{
|
||||
if (revents & EV_SIGNAL) {
|
||||
switch (w->signum) {
|
||||
#ifndef __MINGW32__
|
||||
case SIGCHLD:
|
||||
if (!is_plugin_running())
|
||||
LOGE("plugin service exit unexpectedly");
|
||||
else
|
||||
return;
|
||||
#endif
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_stop(EV_DEFAULT, &sigchld_watcher);
|
||||
#endif
|
||||
ev_unloop(EV_A_ EVUNLOOP_ALL);
|
||||
}
|
||||
}
|
||||
@@ -1493,7 +1506,9 @@ main(int argc, char **argv)
|
||||
char *server_port = NULL;
|
||||
char *plugin_opts = NULL;
|
||||
char *plugin_port = NULL;
|
||||
#ifndef __MINGW32__
|
||||
char tmp_port[8];
|
||||
#endif
|
||||
|
||||
int server_num = 0;
|
||||
const char *server_host[MAX_REMOTE_NUM];
|
||||
@@ -1717,7 +1732,12 @@ main(int argc, char **argv)
|
||||
|
||||
remote_port = server_port;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#endif
|
||||
|
||||
if (plugin != NULL) {
|
||||
#ifndef __MINGW32__
|
||||
uint16_t port = get_local_port();
|
||||
if (port == 0) {
|
||||
FATAL("failed to find a free port");
|
||||
@@ -1725,6 +1745,9 @@ main(int argc, char **argv)
|
||||
snprintf(tmp_port, 8, "%d", port);
|
||||
plugin_port = server_port;
|
||||
server_port = tmp_port;
|
||||
#else
|
||||
FATAL("plugins not implemented in MinGW port");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (method == NULL) {
|
||||
@@ -1782,16 +1805,20 @@ main(int argc, char **argv)
|
||||
LOGI("enable TCP no-delay");
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
ev_signal_init(&sigint_watcher, signal_cb, SIGINT);
|
||||
ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
|
||||
ev_signal_init(&sigchld_watcher, signal_cb, SIGCHLD);
|
||||
ev_signal_start(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_init(&sigchld_watcher, signal_cb, SIGCHLD);
|
||||
ev_signal_start(EV_DEFAULT, &sigchld_watcher);
|
||||
#endif
|
||||
|
||||
// setup keys
|
||||
LOGI("initializing ciphers... %s", method);
|
||||
@@ -1808,6 +1835,7 @@ main(int argc, char **argv)
|
||||
if (nameservers != NULL)
|
||||
LOGI("using nameserver: %s", nameservers);
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// Start plugin server
|
||||
if (plugin != NULL) {
|
||||
int len = 0;
|
||||
@@ -1827,6 +1855,7 @@ main(int argc, char **argv)
|
||||
FATAL("failed to start the plugin");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// initialize listen context
|
||||
listen_ctx_t listen_ctx_list[server_num];
|
||||
@@ -1888,14 +1917,17 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (manager_addr != NULL) {
|
||||
ev_timer_init(&stat_update_watcher, stat_update_cb, UPDATE_INTERVAL, UPDATE_INTERVAL);
|
||||
ev_timer_start(EV_DEFAULT, &stat_update_watcher);
|
||||
}
|
||||
#endif
|
||||
|
||||
ev_timer_init(&block_list_watcher, block_list_clear_cb, UPDATE_INTERVAL, UPDATE_INTERVAL);
|
||||
ev_timer_start(EV_DEFAULT, &block_list_watcher);
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// setuid
|
||||
if (user != NULL && !run_as(user)) {
|
||||
FATAL("failed to switch user");
|
||||
@@ -1904,6 +1936,7 @@ main(int argc, char **argv)
|
||||
if (geteuid() == 0) {
|
||||
LOGI("running from root user");
|
||||
}
|
||||
#endif
|
||||
|
||||
// init block list
|
||||
init_block_list();
|
||||
@@ -1921,15 +1954,19 @@ main(int argc, char **argv)
|
||||
// Free block list
|
||||
free_block_list();
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (manager_addr != NULL) {
|
||||
ev_timer_stop(EV_DEFAULT, &stat_update_watcher);
|
||||
}
|
||||
#endif
|
||||
|
||||
ev_timer_stop(EV_DEFAULT, &block_list_watcher);
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (plugin != NULL) {
|
||||
stop_plugin();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Clean up
|
||||
|
||||
@@ -1953,5 +1990,9 @@ main(int argc, char **argv)
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#ifndef _STREAM_H
|
||||
#define _STREAM_H
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* malloc() */
|
||||
#include <string.h> /* strncpy() */
|
||||
#ifndef __MINGW32__
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "tls.h"
|
||||
#include "protocol.h"
|
||||
|
||||
+36
-3
@@ -29,13 +29,13 @@
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "utils.h"
|
||||
#include "plugin.h"
|
||||
#include "tunnel.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#ifndef EAGAIN
|
||||
#define EAGAIN EWOULDBLOCK
|
||||
@@ -98,8 +99,11 @@ static int no_delay = 0;
|
||||
|
||||
static struct ev_signal sigint_watcher;
|
||||
static struct ev_signal sigterm_watcher;
|
||||
#ifndef __MINGW32__
|
||||
static struct ev_signal sigchld_watcher;
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
static int
|
||||
setnonblocking(int fd)
|
||||
{
|
||||
@@ -109,6 +113,7 @@ setnonblocking(int fd)
|
||||
}
|
||||
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
create_and_bind(const char *addr, const char *port)
|
||||
@@ -738,16 +743,20 @@ signal_cb(EV_P_ ev_signal *w, int revents)
|
||||
{
|
||||
if (revents & EV_SIGNAL) {
|
||||
switch (w->signum) {
|
||||
#ifndef __MINGW32__
|
||||
case SIGCHLD:
|
||||
if (!is_plugin_running())
|
||||
LOGE("plugin service exit unexpectedly");
|
||||
else
|
||||
return;
|
||||
#endif
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_stop(EV_DEFAULT, &sigchld_watcher);
|
||||
#endif
|
||||
keep_resolving = 0;
|
||||
ev_unloop(EV_A_ EVUNLOOP_ALL);
|
||||
}
|
||||
@@ -778,7 +787,9 @@ main(int argc, char **argv)
|
||||
char *plugin_opts = NULL;
|
||||
char *plugin_host = NULL;
|
||||
char *plugin_port = NULL;
|
||||
#ifndef __MINGW32__
|
||||
char tmp_port[8];
|
||||
#endif
|
||||
|
||||
int remote_num = 0;
|
||||
ss_addr_t remote_addr[MAX_REMOTE_NUM];
|
||||
@@ -993,7 +1004,12 @@ main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#endif
|
||||
|
||||
if (plugin != NULL) {
|
||||
#ifndef __MINGW32__
|
||||
uint16_t port = get_local_port();
|
||||
if (port == 0) {
|
||||
FATAL("failed to find a free port");
|
||||
@@ -1003,6 +1019,9 @@ main(int argc, char **argv)
|
||||
plugin_port = tmp_port;
|
||||
|
||||
LOGI("plugin \"%s\" enabled", plugin);
|
||||
#else
|
||||
FATAL("plugins not implemented in MinGW port");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (method == NULL) {
|
||||
@@ -1046,6 +1065,7 @@ main(int argc, char **argv)
|
||||
FATAL("tunnel port is not defined");
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (plugin != NULL) {
|
||||
int len = 0;
|
||||
size_t buf_size = 256 * remote_num;
|
||||
@@ -1062,17 +1082,22 @@ main(int argc, char **argv)
|
||||
FATAL("failed to start the plugin");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
ev_signal_init(&sigint_watcher, signal_cb, SIGINT);
|
||||
ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
|
||||
ev_signal_init(&sigchld_watcher, signal_cb, SIGCHLD);
|
||||
ev_signal_start(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigterm_watcher);
|
||||
#ifndef __MINGW32__
|
||||
ev_signal_init(&sigchld_watcher, signal_cb, SIGCHLD);
|
||||
ev_signal_start(EV_DEFAULT, &sigchld_watcher);
|
||||
#endif
|
||||
|
||||
// Setup keys
|
||||
LOGI("initializing ciphers... %s", method);
|
||||
@@ -1149,6 +1174,7 @@ main(int argc, char **argv)
|
||||
LOGI("TCP relay disabled");
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// setuid
|
||||
if (user != NULL && !run_as(user)) {
|
||||
FATAL("failed to switch user");
|
||||
@@ -1157,12 +1183,19 @@ main(int argc, char **argv)
|
||||
if (geteuid() == 0) {
|
||||
LOGI("running from root user");
|
||||
}
|
||||
#endif
|
||||
|
||||
ev_run(loop, 0);
|
||||
|
||||
#ifndef __MINGW32__
|
||||
if (plugin != NULL) {
|
||||
stop_plugin();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+11
-8
@@ -29,13 +29,13 @@
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "netutils.h"
|
||||
#include "cache.h"
|
||||
#include "udprelay.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#ifdef MODULE_REMOTE
|
||||
#define MAX_UDP_CONN_NUM 512
|
||||
@@ -105,6 +106,7 @@ static int buf_size = DEFAULT_PACKET_SIZE * 2;
|
||||
static int server_num = 0;
|
||||
static server_ctx_t *server_ctx_list[MAX_REMOTE_NUM] = { NULL };
|
||||
|
||||
#ifndef __MINGW32__
|
||||
static int
|
||||
setnonblocking(int fd)
|
||||
{
|
||||
@@ -114,6 +116,7 @@ setnonblocking(int fd)
|
||||
}
|
||||
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MODULE_REMOTE) && defined(SO_BROADCAST)
|
||||
static int
|
||||
@@ -724,7 +727,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
goto CLEAN_UP;
|
||||
} else if (r > packet_size) {
|
||||
if (verbose) {
|
||||
LOGI("[udp] remote_recv_recvfrom fragmentation, MTU at least be: %zd", r + PACKET_HEADER_SIZE);
|
||||
LOGI("[udp] remote_recv_recvfrom fragmentation, MTU at least be: " SSIZE_FMT, r + PACKET_HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -798,7 +801,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
if (buf->len > packet_size) {
|
||||
if (verbose) {
|
||||
LOGI("[udp] remote_recv_sendto fragmentation, MTU at least be: %zd", buf->len + PACKET_HEADER_SIZE);
|
||||
LOGI("[udp] remote_recv_sendto fragmentation, MTU at least be: " SSIZE_FMT, buf->len + PACKET_HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -902,7 +905,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
goto CLEAN_UP;
|
||||
} else if (buf->len > packet_size) {
|
||||
if (verbose) {
|
||||
LOGI("[udp] UDP server_recv_recvmsg fragmentation, MTU at least be: %zd", buf->len + PACKET_HEADER_SIZE);
|
||||
LOGI("[udp] UDP server_recv_recvmsg fragmentation, MTU at least be: " SSIZE_FMT, buf->len + PACKET_HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,7 +927,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
goto CLEAN_UP;
|
||||
} else if (r > packet_size) {
|
||||
if (verbose) {
|
||||
LOGI("[udp] server_recv_recvfrom fragmentation, MTU at least be: %zd", r + PACKET_HEADER_SIZE);
|
||||
LOGI("[udp] server_recv_recvfrom fragmentation, MTU at least be: " SSIZE_FMT, r + PACKET_HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,7 +1211,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
if (buf->len > packet_size) {
|
||||
if (verbose) {
|
||||
LOGI("[udp] server_recv_sendto fragmentation, MTU at least be: %zd", buf->len + PACKET_HEADER_SIZE);
|
||||
LOGI("[udp] server_recv_sendto fragmentation, MTU at least be: " SSIZE_FMT, buf->len + PACKET_HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1225,7 +1228,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
if (buf->len - addr_header_len > packet_size) {
|
||||
if (verbose) {
|
||||
LOGI("[udp] server_recv_sendto fragmentation, MTU at least be: %zd", buf->len - addr_header_len + PACKET_HEADER_SIZE);
|
||||
LOGI("[udp] server_recv_sendto fragmentation, MTU at least be: " SSIZE_FMT, buf->len - addr_header_len + PACKET_HEADER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-2
@@ -25,12 +25,14 @@
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#ifndef __MINGW32__
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -55,12 +57,14 @@ FILE *logfile;
|
||||
int use_syslog = 0;
|
||||
#endif
|
||||
|
||||
#ifndef __MINGW32__
|
||||
void
|
||||
ERROR(const char *s)
|
||||
{
|
||||
char *msg = strerror(errno);
|
||||
LOGE("%s: %s", s, msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
int use_tty = 1;
|
||||
|
||||
@@ -102,6 +106,7 @@ ss_isnumeric(const char *s)
|
||||
int
|
||||
run_as(const char *user)
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
if (user[0]) {
|
||||
/* Convert user to a long integer if it is a non-negative number.
|
||||
* -1 means it is a user name. */
|
||||
@@ -195,6 +200,9 @@ run_as(const char *user)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
LOGE("run_as(): not implemented in MinGW port");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -400,6 +408,7 @@ usage()
|
||||
void
|
||||
daemonize(const char *path)
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
/* Our process ID and Session ID */
|
||||
pid_t pid, sid;
|
||||
|
||||
@@ -444,6 +453,9 @@ daemonize(const char *path)
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
#else
|
||||
LOGE("daemonize(): not implemented in MinGW port");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
@@ -478,6 +490,7 @@ set_nofile(int nofile)
|
||||
char *
|
||||
get_default_conf(void)
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
static char sysconf[] = "/etc/shadowsocks-libev/config.json";
|
||||
static char userconf[PATH_MAX] = { 0 };
|
||||
char *conf_home;
|
||||
@@ -498,4 +511,7 @@ get_default_conf(void)
|
||||
|
||||
// If not, fall back to the system-wide config.
|
||||
return sysconf;
|
||||
#else
|
||||
return "config.json";
|
||||
#endif
|
||||
}
|
||||
|
||||
+48
@@ -87,6 +87,35 @@ extern FILE *logfile;
|
||||
|
||||
#else // not LIB_ONLY
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
#define USE_TTY()
|
||||
#define USE_SYSLOG(ident, _cond)
|
||||
#define USE_LOGFILE(ident)
|
||||
#define TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
#define LOGI(format, ...) \
|
||||
do { \
|
||||
time_t now = time(NULL); \
|
||||
char timestr[20]; \
|
||||
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
|
||||
fprintf(stdout, " %s INFO: " format "\n", timestr, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define LOGE(format, ...) \
|
||||
do { \
|
||||
time_t now = time(NULL); \
|
||||
char timestr[20]; \
|
||||
strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \
|
||||
fprintf(stdout, " %s ERROR: " format "\n", timestr, \
|
||||
## __VA_ARGS__); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
#else // not __MINGW32__
|
||||
|
||||
#include <syslog.h>
|
||||
extern int use_tty;
|
||||
extern int use_syslog;
|
||||
@@ -146,11 +175,30 @@ extern int use_syslog;
|
||||
} } \
|
||||
while (0)
|
||||
|
||||
#endif // if __MINGW32__
|
||||
|
||||
#endif // if LIB_ONLY
|
||||
|
||||
#endif // if __ANDROID__
|
||||
|
||||
// Workaround for "%z" in Windows printf
|
||||
#ifdef __MINGW32__
|
||||
#define SSIZE_FMT "%Id"
|
||||
#define SIZE_FMT "%Iu"
|
||||
#else
|
||||
#define SSIZE_FMT "%zd"
|
||||
#define SIZE_FMT "%zu"
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
#define ERROR(s) ss_error(s)
|
||||
void ss_error(const char *s); // Implemented in winsock.c
|
||||
#else
|
||||
void ERROR(const char *s);
|
||||
#endif
|
||||
|
||||
char *ss_itoa(int i);
|
||||
int ss_isnumeric(const char *s);
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* winsock.c - Windows socket compatibility layer
|
||||
*
|
||||
* Copyright (C) 2013 - 2018, Max Lv <max.c.lv@gmail.com>
|
||||
*
|
||||
* This file is part of the shadowsocks-libev.
|
||||
*
|
||||
* shadowsocks-libev is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* shadowsocks-libev is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with shadowsocks-libev; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
#include "winsock.h"
|
||||
#include "utils.h"
|
||||
|
||||
void
|
||||
winsock_init(void)
|
||||
{
|
||||
int ret;
|
||||
WSADATA wsa_data;
|
||||
ret = WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||
if (ret != 0) {
|
||||
FATAL("Failed to initialize winsock");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
winsock_cleanup(void)
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
int
|
||||
setnonblocking(SOCKET socket)
|
||||
{
|
||||
u_long arg = 1;
|
||||
return ioctlsocket(socket, FIONBIO, &arg);
|
||||
}
|
||||
|
||||
void
|
||||
ss_error(const char *s)
|
||||
{
|
||||
char *msg = NULL;
|
||||
DWORD err = WSAGetLastError();
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&msg, 0, NULL);
|
||||
if (msg != NULL) {
|
||||
// Remove trailing newline character
|
||||
ssize_t len = strlen(msg) - 1;
|
||||
if (len >= 0 && msg[len] == '\n') {
|
||||
msg[len] = '\0';
|
||||
}
|
||||
LOGE("%s: [%ld] %s", s, err, msg);
|
||||
LocalFree(msg);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __MINGW32__
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* winsock.h - Windows socket compatibility layer
|
||||
*
|
||||
* Copyright (C) 2013 - 2018, Max Lv <max.c.lv@gmail.com>
|
||||
*
|
||||
* This file is part of the shadowsocks-libev.
|
||||
*
|
||||
* shadowsocks-libev is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* shadowsocks-libev is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with shadowsocks-libev; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _WINSOCK_H
|
||||
#define _WINSOCK_H
|
||||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
// Override error number
|
||||
#ifdef errno
|
||||
#undef errno
|
||||
#endif
|
||||
#define errno WSAGetLastError()
|
||||
|
||||
#ifdef EWOULDBLOCK
|
||||
#undef EWOULDBLOCK
|
||||
#endif
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
|
||||
#ifdef CONNECT_IN_PROGRESS
|
||||
#undef CONNECT_IN_PROGRESS
|
||||
#endif
|
||||
#define CONNECT_IN_PROGRESS WSAEWOULDBLOCK
|
||||
|
||||
// Override close function
|
||||
#define close(fd) closesocket(fd)
|
||||
|
||||
// Override MinGW functions
|
||||
#define setsockopt(a,b,c,d,e) setsockopt(a,b,c,(const char *)(d),e)
|
||||
#define inet_ntop(a,b,c,d) inet_ntop(a,(void *)(b),c,d)
|
||||
|
||||
// Override Windows built-in functions
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
#define ERROR(s) ss_error(s)
|
||||
#ifndef _UTILS_H
|
||||
void ss_error(const char *s);
|
||||
#endif
|
||||
|
||||
// Missing unistd.h functions
|
||||
#define sleep(x) Sleep((x) * 1000)
|
||||
|
||||
// Winsock compatibility functions
|
||||
int setnonblocking(SOCKET socket);
|
||||
void winsock_init(void);
|
||||
void winsock_cleanup(void);
|
||||
|
||||
#endif // __MINGW32__
|
||||
|
||||
#endif // _WINSOCK_H
|
||||
Reference in New Issue
Block a user