Giter Club home page Giter Club logo

Comments (14)

rofl0r avatar rofl0r commented on July 22, 2024

I can provide traces if needed

yeah, let's start with a strace including the startup of microsocks and an outgoing connection that tries bind to v4 addr but fails. also info about network adapters and netstat.

from microsocks.

olili avatar olili commented on July 22, 2024

here you are:

root@fr0:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/void
    inet 127.0.0.1/32 scope host venet0
       valid_lft forever preferred_lft forever
    inet 145.239.124.222/32 brd 145.239.124.222 scope global venet0:0
       valid_lft forever preferred_lft forever
    inet6 2001:41d0:203:9ad1::6758:cde7/128 scope global
       valid_lft forever preferred_lft forever
root@fr0:~# strace /usr/bin/microsocks -i :: -b 145.239.124.222
execve("/usr/bin/microsocks", ["/usr/bin/microsocks", "-i", "::", "-b", "145.239.124.222"], [/* 13 vars */]) = 0
brk(NULL)                               = 0x55ec3fe36000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=48358, ...}) = 0
mmap(NULL, 48358, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4f06f57000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0Pa\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=135440, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4f06f55000
mmap(NULL, 2212936, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4f06b23000
mprotect(0x7f4f06b3b000, 2093056, PROT_NONE) = 0
mmap(0x7f4f06d3a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f4f06d3a000
mmap(0x7f4f06d3c000, 13384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4f06d3c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\4\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1689360, ...}) = 0
mmap(NULL, 3795296, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4f06784000
mprotect(0x7f4f06919000, 2097152, PROT_NONE) = 0
mmap(0x7f4f06b19000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x195000) = 0x7f4f06b19000
mmap(0x7f4f06b1f000, 14688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4f06b1f000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4f06f53000
arch_prctl(ARCH_SET_FS, 0x7f4f06f53700) = 0
mprotect(0x7f4f06b19000, 16384, PROT_READ) = 0
mprotect(0x7f4f06d3a000, 4096, PROT_READ) = 0
mprotect(0x55ec3f1ae000, 4096, PROT_READ) = 0
mprotect(0x7f4f06f63000, 4096, PROT_READ) = 0
munmap(0x7f4f06f57000, 48358)           = 0
set_tid_address(0x7f4f06f539d0)         = 3341
set_robust_list(0x7f4f06f539e0, 24)     = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f4f06b28bd0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f4f06b340e0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f4f06b28c60, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f4f06b340e0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f4f067b7060}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
brk(NULL)                               = 0x55ec3fe36000
brk(0x55ec3fe57000)                     = 0x55ec3fe57000
socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET6, sin6_port=htons(1080), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 0
listen(3, 4096)                         = 0
accept(3, {sa_family=AF_INET6, sin6_port=htons(58419), inet_pton(AF_INET6, "::ffff:37.209.62.191", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 4
mmap(NULL, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f4f06f5a000
mprotect(0x7f4f06f5a000, 4096, PROT_NONE) = 0
clone(child_stack=0x7f4f06f61ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f4f06f629d0, tls=0x7f4f06f62700, child_tidptr=0x7f4f06f629d0) = 3344
accept(3, client[4] ::ffff:37.209.62.191: connected to ident.me:80
{sa_family=AF_INET6, sin6_port=htons(58422), inet_pton(AF_INET6, "2a02:8070:21c3:4c00:b191:4c35:7a2f:5b74", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 5
mmap(NULL, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f4f06f4a000
mprotect(0x7f4f06f4a000, 4096, PROT_NONE) = 0
clone(child_stack=0x7f4f06f51ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f4f06f529d0, tls=0x7f4f06f52700, child_tidptr=0x7f4f06f529d0) = 3347
accept(3, client[5] 2a02:8070:21c3:4c00:b191:4c35:7a2f:5b74: connected to ident.me:80

to accesses are logged:

C:\Users\Oli\Desktop\curl>curl -4 -x socks5h://fr0.box0.eu ident.me
2001:41d0:203:9ad1::6758:cde7
C:\Users\Oli\Desktop\curl>curl -6 -x socks5h://fr0.box0.eu ident.me
2001:41d0:203:9ad1::6758:cde7

Can you help?

from microsocks.

rofl0r avatar rofl0r commented on July 22, 2024

strace /usr/bin/microsocks

this should have been strace -f as the interesting bit of information (what happens in client thread) is missing.

do you also have netstat -lnat available ?

from microsocks.

olili avatar olili commented on July 22, 2024

sorry, "-f" I forgot...
Attached the traces. Do you need something elses?

dbg.txt

from microsocks.

rofl0r avatar rofl0r commented on July 22, 2024

you seem to be using an old version of microsocks that still uses select(). the strace log is incredibly cluttered thanks to glibc's retarded getaddrinfo() implementation and it took me like 5 mins to find the actual chunk where the outgoing connection happens.

and what happens is odd: bind() call seems to happen with ip passed to -i parameter, not the one of -b parameter.

i've uploaded a static linked microsocks binary to the latest release (direct link: https://github.com/rofl0r/microsocks/releases/download/v1.0.2/microsocks-1.0.2-x86_64-static.xz ) which uses musl libc; it'd interesting if you could test this one instead. (unxz, chmod +x, move to /usr/bin )

from microsocks.

olili avatar olili commented on July 22, 2024

thx a lot!!!!!!

I immediatelly tested it. But it is continously delivering 'invalid argument'
Traces and logs attached. Hopefully this helps.

dbg2.txt

from microsocks.

rofl0r avatar rofl0r commented on July 22, 2024

interesting, this is more conclusive.
the dns result returned for ident.me seems to prefer the ipv6 address (microsocks always uses first result) and so the outgoing socket is bound to AF_INET6; and naturally binding ipv4 address to ivp6 socket fails with EINVAL.

[pid 15601] socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 6
[pid 15601] bind(6, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("145.239.124.222")}, 16) = -1 EINVAL (Invalid argument)

you can probably fix your exact issue by editing /etc/gai.conf to prefer ipv4 over ipv6: https://askubuntu.com/questions/32298/prefer-a-ipv4-dns-lookups-before-aaaaipv6-lookups
(but you then need to use your original glibc-linked binary).
as far as microsocks is concerned, i'm not yet sure whether there's a good "automatic" solution.
just out of interest, could you post the results of host ident.me executed from that vps ?

from microsocks.

olili avatar olili commented on July 22, 2024

changed precedence ::ffff:0:0/96 100 in gai.conf.

Now the listen "0.0.0.0" problem seems to be back. "-i ::" is not listen to 0.0.0.0.
See dbg3.txt

If I start microsocks now with "-i 0.0.0.0" it is at least listening to to IPv4 and outputing corretcly via IPv4.
But It is not reachable by IPv6.
See dbg4.txt

Pls don't hesitiate if you need more traces or tests.

Reverted gai.conf to the old state/original priorities and
host ident.me delievers
ident.me has address 176.58.123.25
ident.me has IPv6 address 2a01:7e00::f03c:91ff:fe70:2b9d
ident.me mail is handled by 20 eforward5.registrar-servers.com.
ident.me mail is handled by 15 eforward4.registrar-servers.com.
ident.me mail is handled by 10 eforward1.registrar-servers.com.
ident.me mail is handled by 10 eforward2.registrar-servers.com.
ident.me mail is handled by 10 eforward3.registrar-servers.com.

from microsocks.

olili avatar olili commented on July 22, 2024

I#m not a very expert on that topic. But wrt getaddrinfo I read in the api:
ai_family
This field specifies the desired address family for the
returned addresses. Valid values for this field include
AF_INET and AF_INET6. The value AF_UNSPEC indicates that
getaddrinfo() should return socket addresses for any
address family (either IPv4 or IPv6, for example) that can
be used with node and service.

Your resolver is AF_UNSPEC (if I understand the code correctly). So it's somehow undetermined. Maybe you have to distinguish this dependend on the address type requested by -i and -b.

from microsocks.

rofl0r avatar rofl0r commented on July 22, 2024

i won't have time to look into this today to find a good solution. i guess one thing one could do is to iterate over gai results and prefer family matching the bind address. anyway, still unsure.
what you could try in the meantime is to simply run two instances of microsocks, one listening on "0.0.0.0" and second one on "::". the starting order could matter. it should be possible to use the same port.

from microsocks.

olili avatar olili commented on July 22, 2024

resolved the issue by modifying of the resolver part. Thx for your support and this very smart tool
O.

microsocks.zip

from microsocks.

rofl0r avatar rofl0r commented on July 22, 2024

can you paste a diff your work ? so i (and everyone else reading this) dont have to download, extract, diff themselves. (just run git diff in your clone and paste output)

from microsocks.

olili avatar olili commented on July 22, 2024

sure.
in server.c:

int resolve(const char *host, unsigned short port, struct addrinfo** addr, int aimode) {
	struct addrinfo hints = {
		.ai_family = aimode,   //UNSPEC,
		.ai_socktype = SOCK_STREAM,
		.ai_flags = AI_PASSIVE,
	};
	char port_buf[8];
	snprintf(port_buf, sizeof port_buf, "%u", port);
	return getaddrinfo(host, port_buf, &hints, addr);
}

int resolve_sa(const char *host, unsigned short port, union sockaddr_union *res, int *aimode ) {
	struct addrinfo hints, *ainfo = 0;
	int ret;

  memset (&hints, 0, sizeof (hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags |= AI_PASSIVE;

	char port_buf[8];
	snprintf(port_buf, sizeof port_buf, "%u", port);

  if ((ret = getaddrinfo (host, port_buf, &hints, &ainfo))) return ret;

  *aimode =  ainfo->ai_family; 

  memcpy(res, ainfo->ai_addr, ainfo->ai_addrlen);
  freeaddrinfo(ainfo);
  
 	return 0;
}

Also update of the respective h:
int resolve(const char host, unsigned short port, struct addrinfo* addr, int aimode);
int resolve_sa(const char *host, unsigned short port, union sockaddr_union *res, int *aimode );

In socketsrv.c:
some small changes, see atachment
diff_socketsrv.pdf

`

from microsocks.

rofl0r avatar rofl0r commented on July 22, 2024
diff --git a/server.c b/server.c
index 9f0ab9a..1730db9 100644
--- a/server.c
+++ b/server.c
@@ -3,9 +3,9 @@
 #include <string.h>
 #include <unistd.h>
 
-int resolve(const char *host, unsigned short port, struct addrinfo** addr) {
+int resolve(const char *host, unsigned short port, struct addrinfo** addr, int aimode) {
 	struct addrinfo hints = {
-		.ai_family = AF_UNSPEC,
+		.ai_family = aimode,   //UNSPEC,
 		.ai_socktype = SOCK_STREAM,
 		.ai_flags = AI_PASSIVE,
 	};
@@ -14,18 +14,30 @@ int resolve(const char *host, unsigned short port, struct addrinfo** addr) {
 	return getaddrinfo(host, port_buf, &hints, addr);
 }
 
-int resolve_sa(const char *host, unsigned short port, union sockaddr_union *res) {
-	struct addrinfo *ainfo = 0;
+int resolve_sa(const char *host, unsigned short port, union sockaddr_union *res, int *aimode ) {
+	struct addrinfo hints, *ainfo = 0;
 	int ret;
-	SOCKADDR_UNION_AF(res) = AF_UNSPEC;
-	if((ret = resolve(host, port, &ainfo))) return ret;
-	memcpy(res, ainfo->ai_addr, ainfo->ai_addrlen);
-	freeaddrinfo(ainfo);
-	return 0;
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags |= AI_PASSIVE;
+
+	char port_buf[8];
+	snprintf(port_buf, sizeof port_buf, "%u", port);
+
+  if ((ret = getaddrinfo (host, port_buf, &hints, &ainfo))) return ret;
+
+  *aimode =  ainfo->ai_family; 
+
+  memcpy(res, ainfo->ai_addr, ainfo->ai_addrlen);
+  freeaddrinfo(ainfo);
+  
+ 	return 0;
 }
 
 int bindtoip(int fd, union sockaddr_union *bindaddr) {
-	socklen_t sz = SOCKADDR_UNION_LENGTH(bindaddr);
+    	socklen_t sz = SOCKADDR_UNION_LENGTH(bindaddr);
 	if(sz)
 		return bind(fd, (struct sockaddr*) bindaddr, sz);
 	return 0;
@@ -38,7 +50,7 @@ int server_waitclient(struct server *server, struct client* client) {
 
 int server_setup(struct server *server, const char* listenip, unsigned short port) {
 	struct addrinfo *ainfo = 0;
-	if(resolve(listenip, port, &ainfo)) return -1;
+	if(resolve(listenip, port, &ainfo, AF_UNSPEC)) return -1;
 	struct addrinfo* p;
 	int listenfd = -1;
 	for(p = ainfo; p; p = p->ai_next) {
diff --git a/server.h b/server.h
index 5acf664..827ddc6 100644
--- a/server.h
+++ b/server.h
@@ -38,8 +38,8 @@ struct server {
 	int fd;
 };
 
-int resolve(const char *host, unsigned short port, struct addrinfo** addr);
-int resolve_sa(const char *host, unsigned short port, union sockaddr_union *res);
+int resolve(const char *host, unsigned short port, struct addrinfo** addr, int aimode);
+int resolve_sa(const char *host, unsigned short port, union sockaddr_union *res, int *aimode );
 int bindtoip(int fd, union sockaddr_union *bindaddr);
 
 int server_waitclient(struct server *server, struct client* client);
diff --git a/sockssrv.c b/sockssrv.c
index 98e4622..2cc3959 100644
--- a/sockssrv.c
+++ b/sockssrv.c
@@ -60,6 +60,7 @@ static sblist* auth_ips;
 static pthread_rwlock_t auth_ips_lock = PTHREAD_RWLOCK_INITIALIZER;
 static const struct server* server;
 static union sockaddr_union bind_addr = {.v4.sin_family = AF_UNSPEC};
+static int aimode;
 
 enum socksstate {
 	SS_1_CONNECTED,
@@ -139,7 +140,7 @@ static int connect_socks_target(unsigned char *buf, size_t n, struct client *cli
 	unsigned short port;
 	port = (buf[minlen-2] << 8) | buf[minlen-1];
 	/* there's no suitable errorcode in rfc1928 for dns lookup failure */
-	if(resolve(namebuf, port, &remote)) return -EC_GENERAL_FAILURE;
+	if(resolve(namebuf, port, &remote, aimode)) return -EC_GENERAL_FAILURE;
 	int fd = socket(remote->ai_addr->sa_family, SOCK_STREAM, 0);
 	if(fd == -1) {
 		eval_errno:
@@ -385,15 +386,16 @@ static void zero_arg(char *s) {
 
 int main(int argc, char** argv) {
 	int ch;
-	const char *listenip = "0.0.0.0";
+	const char *listenip = "::";
+	aimode = AF_UNSPEC;
 	unsigned port = 1080;
-	while((ch = getopt(argc, argv, ":1b:i:p:u:P:")) != -1) {
+	while((ch = getopt(argc, argv, ":m:1b:i:p:u:P:")) != -1) {
 		switch(ch) {
 			case '1':
 				auth_ips = sblist_new(sizeof(union sockaddr_union), 8);
 				break;
 			case 'b':
-				resolve_sa(optarg, 0, &bind_addr);
+				resolve_sa(optarg, 0, &bind_addr, &aimode);
 				break;
 			case 'u':
 				auth_user = strdup(optarg);
@@ -409,6 +411,11 @@ int main(int argc, char** argv) {
 			case 'p':
 				port = atoi(optarg);
 				break;
+//			case 'm':
+//				if ( atoi(optarg) == 4) aimode = PF_INET; 
+//				if ( atoi(optarg) == 6) aimode = AF_INET6;
+//				printf("GetAddressInfo Mode: IPv%d \n",  atoi(optarg) );
+//				break;
 			case ':':
 				dprintf(2, "error: option -%c requires an operand\n", optopt);
 				/* fall through */
@@ -424,6 +431,11 @@ int main(int argc, char** argv) {
 		dprintf(2, "error: auth-once option must be used together with user/pass\n");
 		return 1;
 	}
+	
+	if ( aimode == AF_INET ) printf("ipV4 only for GetAddressInfo\n");
+	if ( aimode == AF_INET6 ) printf("ipV6 only for GetAddressInfo\n");
+	if ( aimode == AF_UNSPEC ) printf("ipv4 + ipv6 for GetAddressInfo\n");
+	
 	signal(SIGPIPE, SIG_IGN);
 	struct server s;
 	sblist *threads = sblist_new(sizeof (struct thread*), 8);

http://ix.io/3w7M

from microsocks.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.