-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
-b IPv4 not working #40
Comments
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. |
here you are:
to accesses are logged:
Can you help? |
this should have been do you also have netstat -lnat available ? |
sorry, "-f" I forgot... |
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 ) |
thx a lot!!!!!! I immediatelly tested it. But it is continously delivering 'invalid argument' |
interesting, this is more conclusive.
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 |
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. If I start microsocks now with "-i 0.0.0.0" it is at least listening to to IPv4 and outputing corretcly via IPv4. Pls don't hesitiate if you need more traces or tests. Reverted gai.conf to the old state/original priorities and |
I#m not a very expert on that topic. But wrt getaddrinfo I read in the api: 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. |
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. |
resolved the issue by modifying of the resolver part. Thx for your support and this very smart tool |
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) |
sure.
Also update of the respective h: In socketsrv.c: ` |
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); |
If `-b bindaddr` is used, then created sockets must be of the same address family as `bindaddr` (otherwise, calls to `bind()` will fail). This patch harmonizes the address family across the calls to `socket()`, `bind()`, and `connect()`. Prior to this patch, `microsocks` would use the first `addrinfo` record returned by `getaddrinfo()`. On systems with both IPv4 and IPv6, sometimes the address family of the first record would be a mismatch with `bindaddr`, resulting in an error. This patch may fix issue rofl0r#30. (And issue rofl0r#40?)
If `-b bindaddr` is used, then created sockets must be of the same address family as `bindaddr` (otherwise, calls to `bind()` will fail). This patch harmonizes the address family across the calls to `socket()`, `bind()`, and `connect()`. Prior to this patch, `microsocks` would use the first `addrinfo` record returned by `getaddrinfo()`. On systems with both IPv4 and IPv6, sometimes the address family of the first record would be a mismatch with `bindaddr`, resulting in an error. This patch may fix issue rofl0r#30. (And issue rofl0r#40?)
If `-b bindaddr` is used, then created sockets must be of the same address family as `bindaddr`, otherwise, calls to `bind()` will fail. This patch harmonizes the address family across the calls to `socket()`, `bind()`, and `connect()`. Prior to this patch, `microsocks` would use the first `addrinfo` record returned by `getaddrinfo()`. On systems with both IPv4 and IPv6, sometimes the address family of the first record would be a mismatch with `bindaddr`, resulting in an error. Fixes #30. (And possibly #40)
Hello,
with some big support from outside, microsocks is finally listening on 0.0.0.0. Thx.
Nevertheless I still have the problem to bind target output to an IPv4 address.
Option "-b IPv4" is ignored on my Deb9+ systems and IPv6 addresses are bound/used.
Is there any hint or trick in order to motivate microsocks to use the IPv4 addresses on these systems for target adresses?
I can provide traces if needed. No problem.
Thx in advance
Oliver
The text was updated successfully, but these errors were encountered: