使用抽象命名空间unix套接字

时间:2015-11-01 17:36:55

标签: python c sockets unix unix-socket

我在使用Python和"纯"时使用所谓的抽象命名空间的unix socket(US)有一个奇怪的问题。 C(Python 3.x但看起来像2.x有同样的问题)。 "正常"插座就像一个魅力。随着"抽象"一个美国我的代码只有在我使用相同的代码平台" (C或Python)。

首先我认为它与memset / str(n)cpy有关(请参阅Can not connect to an abstract unix socket in python),但事实并非如此。

测试矩阵(srv - server,cli - client):

  • srv + cli @" abstract" unix袜子:
    • python + python =确定
    • c + c =确定
  • srv + cli @" normal" unix袜子:
    • python + python =确定
    • c + c =确定
  • srv + cli @" normal" unix袜子:
    • python + c =确定
    • c + python =确定
  • srv + cli @" abstract" unix袜子:
    • python + c =失败[cli / strace输出:ECONNREFUSED(拒绝连接)]
    • c + python = FAIL [cli / raise exception:socket.error:[Errno 111] Connection refused]

/proc/net/unix / lsofstrace没有显示任何异常:

  • 工作"正常" socket C客户端:
    // ...
    socket(PF_LOCAL, SOCK_STREAM, 0) = 3
    connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = 0
    // ...

  • 行为不端"摘要" socket C客户端:
    // ...
    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还是什么......?

使用我的测试矩阵的代码示例:https://gist.github.com/soutys/ffbe2e76a86835a9cc6b

原始代码/样本:

更新2015-11-02

有关系统和汇编的更多信息:

  • 主机系统:Ubuntu 14.04.3 LTS(x64);
  • 使用gcc编译的所有C测试文件(例如:gcc -Wall -Wextra -pedantic -o abs_cli abs_cli.c);
  • 所有程序(编译和内置的python)都以非root用户身份运行;

1 个答案:

答案 0 :(得分:0)

将UNIX域套接字绑定到抽象名称时,addrlen参数应为sizeof(struct sockaddr_un的sun_family)+抽象名称中的字符数+ 1.“+1”用于抽象前面的空字节sockaddr_un的sun_path中的名字。我们来看一个例子:

  • C中的服务器

    int sockfd;
    struct sockaddr_un addr;
    /* create socket, set addr.sun_family, set addr.sun_path to 
       null byte followed by abstract_name */
    bind(sockfd, (struct sockaddr *)&addr, sizeof(addr.sun_family) +
         strlen(abstract_name) + 1);
    
  • Python中的客户端:

    client = socket.socket(socket.AF_UNIX, ...)
    client.connect( "\0abstract_name" )
    

参考文献: