On 23/04/16 03:36, Jonathan Vanasco wrote:
Thanks for all this.

A few quick notes:

On Apr 20, 2016, at 9:15 PM, Glyph wrote:

This isn't so much a feature of Python as it is a feature of the BSD
sockets API.  Sending traffic through a socket, whether it's TCP or
UDP, has to bind a client port.  Given the nature of UDP, binding on
all interfaces is the expectation unless you specify.

I didn't have time to test a simple C program before sending this
message, but
https://github.com/python/cpython/blob/master/Modules/socketmodule.c only
calls "bind()" from sock_bind, not from send(), nor does
https://github.com/python/cpython/blob/master/Lib/socket.py engage in
any such shenanigans.

The 'feature' of Python is a few things:

 From what I could tell, the actual communication and binding happens
somewhere in the c module.


Not so. It's down inside the kernel. All applications using the socket API in this way will display this behaviour, regardless of language.

Seriously, try it and see:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
        int s,r;
        struct sockaddr_in dst;
        dst.sin_family = AF_INET;
        dst.sin_port = htons(37);
        dst.sin_addr.s_addr = INADDR_LOOPBACK;

        s = socket(AF_INET, SOCK_DGRAM, 0);
        printf("socket created\n");
        sleep(30);
        sendto(s, "foo", 3, 0, &dst, sizeof(dst));
        printf("socket used\n");
        sleep(30);
        return 0;
}

Compile & run the program and quickly lsof the process, you'll see:

test    16258 pjm3    3u  sock    0,8      0t0 87111053 protocol: UDP

...wait until it has printed that it has used the socket, repeat and you'll see:

test    16258 pjm3    3u  IPv4 87111053      0t0     UDP *:51669

As glyph says, this is an inherent feature of the socket API. When you create a socket, it is unbound because you might be about to call bind() yourself.

If you then use it without binding it, the kernel has to allocate a source port, and in turn an interface, and the only sensible choice absent any instructions from userland is INADDR_ANY.

This is definitely not Python doing this.

_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to