python - Connection refused when using abstract namespace unix sockets -
i have strange problem unix socket (us) using so-called abstract namespaces when using python , "pure" c (python 3.x looks 2.x have same problem). "normal" socket works charm. "abstract" 1 code works when i'm using same "code platform" (c or python).
first thought has memset
/ str(n)cpy
(see can not connect abstract unix socket in python) imho it's not case.
test matrix (srv - server, cli - client):
- srv + cli @ "abstract" unix sock:
- python + python = ok
- c + c = ok
- srv + cli @ "normal" unix sock:
- python + python = ok
- c + c = ok
- srv + cli @ "normal" unix sock:
- python + c = ok
- c + python = ok
- srv + cli @ "abstract" unix sock:
- python + c = fail [cli / strace output: econnrefused (connection refused)]
- c + python = fail [cli / raised exception: socket.error: [errno 111] connection refused]
/proc/net/unix
/ lsof
or strace
show nothing unusual:
working "normal" socket c client:
// ...
socket(pf_local, sock_stream, 0) = 3
connect(3, {sa_family=af_local, sun_path=@"/var/tmp/sock.tmp"}, 110) = 0
// ...
misbehaving "abstract" socket c client:
// ...
socket(pf_local, sock_stream, 0) = 3
connect(3, {sa_family=af_local, sun_path=@"/var/tmp/sock.tmp"}, 110) = -1 econnrefused (connection refused)
// ...
python bug or what...?
gist code samples my test matrix: https://gist.github.com/soutys/ffbe2e76a86835a9cc6b
original code / samples:
- c servers/clients - based on https://github.com/troydhanson/network/tree/master/unixdomain
- python servers/clients - based on python 3.x unix socket example
update 2015-11-02
more info system , compilations:
- host system: ubuntu 14.04.3 lts (x64);
- all c test files compiled
gcc
(example:gcc -wall -wextra -pedantic -o abs_cli abs_cli.c
); - all programs (both compiled , built-in python) run non-root user;
when binding unix domain socket abstract name, addrlen argument should sizeof(struct sockaddr_un's sun_family) + number of characters in abstract name + 1. "+1" null byte in front of abstract name in sockaddr_un's sun_path. let's @ example:
server in c:
int sockfd; struct sockaddr_un addr; /* create socket, set addr.sun_family, set addr.sun_path null byte followed abstract_name */ bind(sockfd, (struct sockaddr *)&addr, sizeof(addr.sun_family) + strlen(abstract_name) + 1);
client in python:
client = socket.socket(socket.af_unix, ...) client.connect( "\0abstract_name" )
references:
- the linux programming interface michael kerrisk, example 57-8.
- http://blog.eduardofleury.com/archives/2007/09/13
Comments
Post a Comment