Cannot connect to abstract unix socket in python

I have a server written in C ++ that creates and communicates with an abstract unix socket with the namespace address "\0hidden" . I also have a client that is also written in C ++, and this client can successfully connect to my server. By the way, I do not have the source code for this client. Now I am trying to connect to my server using the client that I wrote in python, without success. I do not understand why my python client is not working. I place the relevant parts of my server and client codes.

Server

 #define UD_SOCKET_PATH "\0hidden" struct sockaddr_un addr; int fd,cl; if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { syslog(LOG_CRIT, "Error creating socket!"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1); unlink(UD_SOCKET_PATH); if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { syslog(LOG_CRIT, "Bind error"); exit(1); } if (listen(fd, MAX_CONN_PENDING) == -1) { syslog(LOG_CRIT, "Listen error"); exit(1); } syslog(LOG_INFO, "Start listening."); 

And my client code

 #! /opt/python/bin/python import os import socket import sys # Create a UDS socket sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server_address = "\0hidden" print >>sys.stderr, 'connecting to %s' % server_address.decode("utf-8") try: sock.connect(server_address) except socket.error, msg: print >>sys.stderr, msg sys.exit(1) 

After starting the client, I get the following error output:

 connecting to hidden [Errno 111] Connection refused 

And for some additional information, I post the relevant parts of the strace results of my working C ++ client and the broken python client:

C ++ working client:

 socket(PF_FILE, SOCK_STREAM, 0) = 3 connect(3, {sa_family=AF_FILE, path=@ ""}, 110) = 0 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d7000 write(1, "Sent message is: 00014 www.googl"..., 38) = 38 write(3, "00014 www.google.com", 20) = 20 recv(3, "014 Search Engines", 99, 0) = 18 write(1, "014 Search Engines\n", 19) = 19 close(3) = 0 exit_group(0) = ? 

There is no python working client:

 socket(PF_FILE, SOCK_STREAM, 0) = 3 connect(3, {sa_family=AF_FILE, path=@ "hidden"...}, 9) = -1 ECONNREFUSED (Connection refused) write(2, "Traceback (most recent call last"..., 35) = 35 write(2, " File \"./uds.py\", line 13, in <"..., 40) = 40 open("./uds.py", O_RDONLY|O_LARGEFILE) = 4 fstat64(4, {st_mode=S_IFREG|0755, st_size=839, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000 read(4, "#! /opt/python/bin/python\nimport"..., 4096) = 839 write(2, " ", 4) = 4 write(2, "sock.connect('\\0hidden')\n", 25) = 25 close(4) = 0 munmap(0xb7792000, 4096) = 0 write(2, " File \"/opt/python/lib/python2."..., 64) = 64 open("/opt/python/lib/python2.7/socket.py", O_RDONLY|O_LARGEFILE) = 4 fstat64(4, {st_mode=S_IFREG|0755, st_size=20234, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000 read(4, "# Wrapper module for _socket, pr"..., 4096) = 4096 read(4, "oo long.\"\n errorTab[10064] = "..., 4096) = 4096 write(2, " ", 4) = 4 write(2, "return getattr(self._sock,name)("..., 39) = 39 close(4) = 0 munmap(0xb7792000, 4096) = 0 write(2, "socket", 6) = 6 write(2, ".", 1) = 1 write(2, "error", 5) = 5 write(2, ": ", 2) = 2 write(2, "[Errno 111] Connection refused", 30) = 30 write(2, "\n", 1) = 1 rt_sigaction(SIGINT, {SIG_DFL, [], 0}, {0x810fbe0, [], 0}, 8) = 0 close(3) = 0 exit_group(1) = ? 

And also, when I start my C ++ client, I get this strace output from my server:

 0, NULL) = 12 futex(0x80646a4, FUTEX_CMP_REQUEUE_PRIVATE, 1, 2147483647, 0x8064688, 360) = 10 futex(0x8064688, FUTEX_WAKE_PRIVATE, 1) = 1 accept(5, 

But when I run my python client, no output is displayed on strace. It looks like I'm trying to connect to the wrong address, but my address is defined as "\0hidden" both on my server and on my client.

+5
source share
1 answer

Your C ++ is not doing what you think. This line:

 strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1); 

Copy the single null character '\0' to addr.sun_path . Pay attention to this line in the man page for strncpy() :

If the length of src is less than n, strncpy () writes an extra null bytes to dest to ensure that only n bytes are written.

As a result, your C ++ actually connects to the abstract domain socket at "\0" . Python does the right thing here and connects to the abstract domain socket in "\0hidden" .

+3
source

All Articles