连接本地socks5服务,报 Can't assign requested address 错误
Closed this issue · 15 comments
苹果对广播包收发存在限制,需要额外申请权限。之前运行在iOS上时会出现Can't assign requested address错误。可能是因为苹果限制导致?所以来求证一下。
没有。先定位错误日志“Can't assign requested address”的来源吧,然后再分析原因。
新的进展:
iPhone、Mac同一网络下。
Mac运行socks5服务(clash),手机端运行hev-socks5-tunnel,IP:MacIP地址,Port:socks5监听端口,iPhone可以通过Mac访问网络。证明对hev-socks5-tunnel的修改应该是没问题的😊。
不错,那基本是调通啦
是这里的问题:
// hev-socks5-client.c
static int
hev_socks5_client_connect_server (HevSocks5Client *self, const char *addr,
int port)
...
struct sockaddr *saddr = NULL;
struct sockaddr_in s;
s.sin_family = AF_INET;
s.sin_port = port;
inet_pton(AF_INET, addr, &s.sin_addr);
memcpy(saddr, &s, sizeof(s));
// res = hev_socks5_resolve_to_sockaddr6 (addr, port, &saddr);
// if (res < 0) {
// LOG_E ("%p socks5 client resolve [%s]:%d", self, addr, port);
// return -1;
// }
...
我自己创建了sockaddr而不使用hev_socks5_resolve_to_sockaddr6返回的sockaddr_in6,就不会出现Can't assign requested address问题。
具体为什么我还不太清楚😅,大佬可以解惑么。
不好意思,Network Extension崩了,我还以为可以了。。。我在看看😅
hev_socks5_resolve_to_sockaddr6
socks5 library都是创建address family为AF_INET6的socket的,如果是IPv4地址,则使用IPv4-mapped IPv6地址,不确定是不是iOS没有启用IPv4-mapped支持导致的,那么可以做两个实验:
- 尝试使用IPv6地址连接socks5 server。
- 将hev_socks5_resolve_to_sockaddr6转换出的sockaddr_in6结果转换回可读字符串,在日志中输出以确认内容正确。
hev_socks5_resolve_to_sockaddr6
socks5 library都是创建address family为AF_INET6的socket的,如果是IPv4地址,则使用IPv4-mapped IPv6地址,不确定是不是iOS没有启用IPv4-mapped支持导致的,那么可以做两个实验:
- 尝试使用IPv6地址连接socks5 server。
- 将hev_socks5_resolve_to_sockaddr6转换出的sockaddr_in6结果转换回可读字符串,在日志中输出以确认内容正确。
本地socks5服务监听::1,客户端address同为::1,连接成功。再也不用编译leaf作tun2socks实现了😂。
代码改动不大。lwip编译的时候需要去掉iOS不支持的函数。
int start_tun2socks (int fd, const char *config_path)
{
const char *log_file;
int tun_fd = -1;
int log_level;
int nofile;
int res;
int dup_fd = dup(fd);
if (dup_fd < 0)
return -100;
int nonblock = 1;
res = ioctl (fd, FIONBIO, (char *)&nonblock);
if (res < 0)
return -200;
tun_fd = fd;
res = hev_task_system_init ();
if (res < 0)
return -2;
res = hev_config_init (config_path);
if (res < 0)
return -3;
log_file = hev_config_get_misc_log_file ();
log_level = hev_config_get_misc_log_level ();
res = hev_logger_init (log_level, log_file);
if (res < 0)
return -4;
res = hev_socks5_logger_init (log_level, log_file);
if (res < 0)
return -5;
nofile = hev_config_get_misc_limit_nofile ();
res = set_limit_nofile (nofile);
if (res < 0)
LOG_W ("set limit nofile");
lwip_init ();
res = hev_socks5_tunnel_init (tun_fd);
if (res < 0)
return -6;
hev_socks5_tunnel_run ();
hev_socks5_tunnel_fini ();
hev_socks5_logger_fini ();
hev_logger_fini ();
hev_config_fini ();
lwip_fini ();
hev_task_system_fini ();
return 0;
}
将hev-socks5-tunnel编译为静态库,再通过libtool将静态库合并。
PROJECT=hev-socks5-tunnel
CROSS_PREFIX :=
PP=xcrun --sdk iphoneos --toolchain iphoneos clang
CC=xcrun --sdk iphoneos --toolchain iphoneos clang
感谢大佬耐心指点。由于C、编译功底较差😂,PR我就不提了。
以下是我得个人想法:
1、在Apple平台上,日志可以使用asl(我在调试的时候使用)
#include <os/log.h>
const os_log_t log_default = OS_LOG_DEFAULT;
os_log_error(log_default, "%{public}s", msg);
2、外部传入fd,那么gateway的初始化,应该可以不需要外部传入gateway相关配置(用Go实现实现过,C还没尝试)。
最后,感谢大佬。
Congratulations!
- 可以把必要的修改先发出来,我们再找时间整理一下集成起来,这样以后维护会方便一些。比如作为库使用的start_tun2socks入口,可以参考Android JNI的方式实现成Apple版的。
- hev_socks5_tunnel_fini时不会关闭外部传入的fd,所以退出时需要close或不要dup。
1、在Apple平台上,日志可以使用asl(我在调试的时候使用)
#include <os/log.h> const os_log_t log_default = OS_LOG_DEFAULT; os_log_error(log_default, "%{public}s", msg);
应该可以把Log的实现对接到目标平台,包括Android的。
2、外部传入fd,那么gateway的初始化,应该可以不需要外部传入gateway相关配置(用Go实现实现过,C还没尝试)。
LwIP网关侧的地址配置目前应该不可省略。
hev-socks5-tunnel:
1、Makefile:PP、CC、CCFLAGS、LDFLAGS修改适用于third-part的Makefile
diff --git a/Makefile b/Makefile
index f9cd33c..463529f 100644
--- a/Makefile
+++ b/Makefile
@@ -3,17 +3,18 @@
PROJECT=hev-socks5-tunnel
CROSS_PREFIX :=
-PP=$(CROSS_PREFIX)cpp
-CC=$(CROSS_PREFIX)gcc
+PP=xcrun --sdk iphoneos --toolchain iphoneos clang
+CC=xcrun --sdk iphoneos --toolchain iphoneos clang
STRIP=$(CROSS_PREFIX)strip
-CCFLAGS=-O3 -pipe -Wall -Werror $(CFLAGS) \
+CCFLAGS=-Wall -O3 -arch arm64 -mios-version-min=16.0 \
-I$(SRCDIR)/misc \
-I$(SRCDIR)/core/include \
-I$(THIRDPARTDIR)/yaml/include \
-I$(THIRDPARTDIR)/lwip/include \
-I$(THIRDPARTDIR)/lwip/include/ports/unix \
-I$(THIRDPARTDIR)/hev-task-system/include
-LDFLAGS=-L$(THIRDPARTDIR)/yaml/bin -lyaml \
+LDFLAGS=-arch arm64 -mios-version-min=16.0 -Wl, -Bsymbolic-functions \
+ -L$(THIRDPARTDIR)/yaml/bin -lyaml \
-L$(THIRDPARTDIR)/lwip/bin -llwip \
-L$(THIRDPARTDIR)/hev-task-system/bin -lhev-task-system \
-lpthread
@@ -39,6 +40,8 @@ LDOBJS=$(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(CCSRCS)) \
$(patsubst $(SRCDIR)/%.S,$(BUILDDIR)/%.o,$(ASSRCS))
DEPEND=$(LDOBJS:.o=.dep)
+STATIC_TARGET=$(BINDIR)/lib$(PROJECT).a
+
BUILDMSG="\e[1;31mBUILD\e[0m %s\n"
LINKMSG="\e[1;34mLINK\e[0m \e[1;32m%s\e[0m\n"
STRIPMSG="\e[1;34mSTRIP\e[0m \e[1;32m%s\e[0m\n"
@@ -60,6 +63,8 @@ endif
.PHONY: all clean install uninstall tp-build tp-clean
+static : $(STATIC_TARGET) tp-build
+
all : $(TARGET)
tp-build : $(THIRDPARTS)
@@ -80,6 +85,11 @@ uninstall :
$(ECHO_PREFIX) $(RM) -rf $(INSTDIR)/etc/$(PROJECT).yml
@printf $(UNINSMSG) $(INSTDIR)/etc/$(PROJECT).yml
+$(STATIC_TARGET) : $(LDOBJS)
+ $(ECHO_PREFIX) mkdir -p $(dir $@)
+ $(ECHO_PREFIX) $(AR) csq $@ $^
+ @printf $(LINKMSG) $@
+
$(INSTDIR)/bin/$(PROJECT) : $(TARGET)
$(ECHO_PREFIX) install -d -m 0755 $(dir $@)
$(ECHO_PREFIX) install -m 0755 $< $@
2、main
diff --git a/src/hev-main.h b/src/hev-main.h
index 0ef7366..eba0444 100644
--- a/src/hev-main.h
+++ b/src/hev-main.h
@@ -10,7 +10,7 @@
#ifndef __HEV_MAIN_H__
#define __HEV_MAIN_H__
-int main (int argc, char *argv[]);
+int start_tun2socks (int tun_fd, const char *config_file_path);
void quit (void);
#endif /* __HEV_MAIN_H__ */
diff --git a/src/hev-main.c b/src/hev-main.c
index a8af3d6..285b18a 100644
--- a/src/hev-main.c
+++ b/src/hev-main.c
@@ -26,14 +26,6 @@
#include "hev-main.h"
-static void
-show_help (const char *self_path)
-{
- printf ("%s CONFIG_PATH [TUN_FD]\n", self_path);
- printf ("Version: %u.%u.%u %s\n", MAJOR_VERSION, MINOR_VERSION,
- MICRO_VERSION, COMMIT_ID);
-}
-
static void
run_as_daemon (const char *pid_file)
{
@@ -85,28 +77,19 @@ lwip_fini (void)
}
int
-main (int argc, char *argv[])
+start_tun2socks (int tun_fd, const char *config_file_path)
{
const char *pid_file;
const char *log_file;
- int tun_fd = -1;
int log_level;
int nofile;
int res;
- if (argc < 2) {
- show_help (argv[0]);
- return -1;
- }
-
- if (argc > 2)
- tun_fd = strtol (argv[2], NULL, 10);
-
res = hev_task_system_init ();
if (res < 0)
return -2;
- res = hev_config_init (argv[1]);
+ res = hev_config_init (config_file_path);
if (res < 0)
return -3;
3、hev-tunnel-macos
diff --git a/src/hev-tunnel-macos.c b/src/hev-tunnel-macos.c
index 8b6893d..9bf8fde 100644
--- a/src/hev-tunnel-macos.c
+++ b/src/hev-tunnel-macos.c
@@ -9,121 +9,28 @@
#if defined(__APPLE__) || defined(__MACH__)
-#include <stdio.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <net/if.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/sys_domain.h>
-#include <sys/kern_control.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <net/if_utun.h>
-#include <netinet6/in6_var.h>
-
#include <hev-task.h>
#include <hev-task-io.h>
-#include "hev-tunnel.h"
-static char tun_name[IFNAMSIZ];
+#include "hev-tunnel.h"
int
hev_tunnel_open (const char *name)
{
- socklen_t len = IFNAMSIZ;
- struct sockaddr_ctl sc;
- struct ctl_info ci;
- int nonblock = 1;
- int res = -1;
- int fd;
-
- memset (&ci, 0, sizeof (ci));
- strncpy (ci.ctl_name, UTUN_CONTROL_NAME, sizeof (ci.ctl_name));
-
- fd = socket (PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
- if (fd < 0)
- goto exit;
-
- res = ioctl (fd, CTLIOCGINFO, &ci);
- if (res < 0)
- goto exit_close;
-
- sc.sc_id = ci.ctl_id;
- sc.sc_len = sizeof (sc);
- sc.sc_family = AF_SYSTEM;
- sc.ss_sysaddr = AF_SYS_CONTROL;
- sc.sc_unit = 0;
-
- res = connect (fd, (struct sockaddr *)&sc, sizeof (sc));
- if (res < 0)
- goto exit_close;
-
- res = ioctl (fd, FIONBIO, (char *)&nonblock);
- if (res < 0)
- goto exit_close;
-
- res = getsockopt (fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, tun_name, &len);
- if (res < 0)
- goto exit_close;
-
- return fd;
-
-exit_close:
- close (fd);
-exit:
- return res;
+ return 0;
}
int
hev_tunnel_set_mtu (int mtu)
{
- struct ifreq ifr = { .ifr_mtu = mtu };
- int res = -1;
- int fd;
-
- fd = socket (AF_INET, SOCK_STREAM, 0);
- if (fd < 0)
- goto exit;
-
- memcpy (ifr.ifr_name, tun_name, IFNAMSIZ);
- res = ioctl (fd, SIOCSIFMTU, (void *)&ifr);
-
- close (fd);
-exit:
- return res;
+ return 0;
}
int
hev_tunnel_set_state (int state)
{
- struct ifreq ifr = { 0 };
- int res = -1;
- int fd;
-
- fd = socket (AF_INET, SOCK_STREAM, 0);
- if (fd < 0)
- goto exit;
-
- memcpy (ifr.ifr_name, tun_name, IFNAMSIZ);
- res = ioctl (fd, SIOCGIFFLAGS, (void *)&ifr);
- if (res < 0)
- goto exit_close;
-
- if (state)
- ifr.ifr_flags |= IFF_UP;
- else
- ifr.ifr_flags &= ~IFF_UP;
- res = ioctl (fd, SIOCSIFFLAGS, (void *)&ifr);
-
-exit_close:
- close (fd);
-exit:
- return res;
+ return 0;
}
int
lwip:
diff --git a/src/ports/unix/port/netif/sio.c b/src/ports/unix/port/netif/sio.c
index 8653fc9..2731519 100644
--- a/src/ports/unix/port/netif/sio.c
+++ b/src/ports/unix/port/netif/sio.c
@@ -436,7 +436,7 @@ sio_fd_t sio_open(u8_t devnum)
"/sbin/ifconfig sl0 mtu %d %s pointopoint %s up",
SLIP_MAX_SIZE, "192.168.2.1", "192.168.2.2");
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: system(\"%s\");\n", siostate->fd, buf));
- ret = system(buf);
+ exit(0);
if (ret < 0) {
perror("ifconfig failed");
exit(1);
diff --git a/src/ports/unix/port/netif/tapif.c b/src/ports/unix/port/netif/tapif.c
index 3d53586..210d2fa 100644
--- a/src/ports/unix/port/netif/tapif.c
+++ b/src/ports/unix/port/netif/tapif.c
@@ -186,7 +186,7 @@ low_level_init(struct netif *netif)
);
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: system(\"%s\");\n", buf));
- ret = system(buf);
+ exit(0);
if (ret < 0) {
perror("ifconfig failed");
exit(1);
基于2.4.5版本的所有修改全在这里了。
好的
- hev_socks5_tunnel_init如果从外部传入的tun fd,则不会执行hev_tunnel_set_xxx,hev-tunnel-macos中一些方法实现需要注释掉是因为编译出错?
- Tun设备事实上配置的MTU是多少?最好Tun设备和LwIP一致,默认为9000。
好的
- hev_socks5_tunnel_init如果从外部传入的tun fd,则不会执行hev_tunnel_set_xxx,hev-tunnel-macos中一些方法实现需要注释掉是因为编译出错?
是的,编译错误
src/hev-tunnel-macos.c:21:10: fatal error: 'sys/sys_domain.h' file not found
#include <sys/sys_domain.h>
^~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [build/hev-tunnel-macos.o] Error 1
- Tun设备事实上配置的MTU是多少?最好Tun设备和LwIP一致,默认为9000。
同为9000,保持和LwIP一致。