Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not connect to an abstract unix socket in python

I have a server written in c++ which creates and binds to an abstract unix socket with a namespace address of "\0hidden". I also have a client which is written in c++ also and this client can successfully connect to my server. BTW, I do not have the source code of this client. Now I am trying to connect to my server using a client I have written in python with no success. I do not understand why my python client is not working. I am posting 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 running the client I get the following error output:

connecting to hidden
[Errno 111] Connection refused

And for some extra information I am posting the relevant parts of the strace outputs of my working c++ client and non-working python client:

Working c++ 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)                           = ?

None working python 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 run 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 shown on strace. So it seems like I am trying to connect to a wrong address, but my address is defined as "\0hidden" in both my server and my client.

like image 649
Alptugay Avatar asked Oct 19 '22 09:10

Alptugay


1 Answers

Your C++ doesn't do quite what you think it does. This line:

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

Copies a single null character '\0' into addr.sun_path. Note this line in the manpage for strncpy():

If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are written.

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

like image 55
Kaiting Chen Avatar answered Oct 21 '22 22:10

Kaiting Chen