Python3: Is a write to UDP socket as file object even possible? - python-3.x

In Python3 I created a socket with s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) in order to send UDP to a certain destination in the network. Now the classical way would be to s.sendto(my_data, (ip, port)). But I would like to handle the socket as an io file object. Therefore I created one by f = s.makefile(mode='wb'). Now I can use f.write(my_data) to send data. But wait ... I never had to specify IP and port. Needless to say, the data does not arrive at the destination. With TCP there is no problem because with s.connect((ip, port)) I can specify ip and port before I create a file object.
Is it possible, and if yes how, to send UDP with a socket as file object?

okey...as I was writing the question it occurred to me that I could try calling s.connect((ip, port)) on the UDP socket although there is no connection to establish. VoilĂ  it works. Maybe this helps somebody.

Related

Is it possible to send TCP packet to a specific port with scapy's send function?

I am trying to send and receive an TCP packet with data on it. My current line of code for sending is:
send(IP(src="1.1.1.1",dst="1.2.3.4")/TCP()/"Test")
How would I specify a Port
I have an simple idea:
port = random.randint(48620, 49150)
If you want to know what is port, go to:
https://www.techtarget.com/searchnetworking/definition/port-number
Thanks

Error when attempting to read from a UDP socket

I create a UDP socket and send data to an address that is not listening. The next time I attempt to receive data, it fails with the error [WinError 10054] An existing connection was forcibly closed by the remote host. As an example, this code will error on the last line. Why and how can I fix it?
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(bytes("A", 'utf-8'), ("127.0.0.1", 5000))
s.recvfrom(128)
I create a UDP socket and send data to an address that is not listening
The answer is in the question. Just make sure that there is a server side logic to send you back data.
Otherwise the OS will send back to your app an ICMP message saying that there is nothing listening on that port, which will trigger the [WinError 10054] that you are reporting. BTW, UDP being in essence a connection-less protocol, the error message cannot be accurate.

what is the difference between socket and sock?

I found that there is "socket: /tmp/mysql.sock" in some config files, so what is the difference between socket and sock ?
sock is an abbreviation of socket (also a sock is something that is worn on the feet).
'Socket' is the technical term for a handle that refers to a network endpoint. It originated in the Unix API for networks, and has since leaked over to Windows.
A socket can refer to TCP connection, a UDP packet endpoint, an X.25 connection, or ... a Unix domain socket, which is a mutant named pipe.
People tend to name Unix domain sockets with 'sock' in the name, but there's no requirement.
Sock is just an abbreviation for socket. But if you see a socket as a file it's a Unix socket as opposed to a TCP socket.
This link has some information on the differences between the two.
http://lists.freebsd.org/pipermail/freebsd-performance/2005-February/001143.html
Basically a TCP socket communicates over the network, and a Unix socket is similar except it can only connect to your localhost. (127.0.0.1)

Linux: how to send TCP packet from specific port?

How to open a raw socket for sending from specific TCP port? I want to have all my connections always go from a range of ports below ephemerals.
If you are using raw sockets, then just fill in the correct TCP source port in the packet header.
If, instead, you are using the TCP socket interface (socket(), connect() and friends), then you can set the source port by calling the bind() system call for the client socket - exactly as you would to set the listening port for the server socket.
Making a tcp connection using raw sockets is somewhere between difficult and impossible; you'd need to implement the entire tcp protocol in your program AND also stop the kernel from sending its own replies to the packets (if the kernel has IP bound on that address on that interface).
This is probably not what you want. However, if you did want it, it is trivial to send tcp frames with any source port you want, as you get to specify it in the tcp header, which of course, if you're implementing your own TCP layer, you'll need to understand.

Socket getting created with same IP and port on local host

I am seeing weird behavior on Linux where I am seeing that remote end and local end are both showing same IP and port combination. Following is the netstat output
netstat -anp | grep 6102
tcp 0 0 139.185.44.123:61020 0.0.0.0:* LISTEN 3361/a.out
tcp 0 0 139.185.44.123:61021 139.185.44.123:61021 ESTABLISHED 3361/a.out
Can anyone tell me if this is even possible ? If yes, then what could be the scenario ?
A connection is identified by a 4-tuple ((source ip, source port), (target ip, target port)), and the source and target ports could conceivably be the same without any issues. This connection could even be established by one process, which would lead to the output you're seeing.
However, I just got bitten by a nasty bug, where a client socket would try to connect to a server socket with a port number in the ephemeral port range on the same machine. The connection operation would be retried operation until it succeeded.
The retry feature was the issue: if the server application wasn't running AND the source port that got picked at random was the same as the target port (which is possible because the target port was in the ephemeral range), the client socket would CONNECT TO ITSELF (which was wreaking havoc on the internal logic of the client application, you can imagine).
Since the client was performing retries as quickly as possible, the 1 in 30.000 odds that this can happen were hit quickly enough.
The following Python script reproduces it:
import socket
host = 'localhost'
port = 35911
ctr = 0
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
ctr += 1
s.connect((host, port))
print "Connected to self after", ctr, "tries"
break
except socket.error, e:
print e
# Retry
Here is an imaginable scenario. The caller of connect could call bind before calling connect. The caller of connect could cooperate with the caller of listen, and intentionally bind to a port number 1 higher than the listening port number.
If the kernel proceeds to reuse the socket number for the listener, I'd call that a kernel bug.
When multi-threaded server software accepts connection, it usually creates another socket, which communicates with newly connected client in separate thread, while original server socket is still listening for new clients in original thread. In such cases ports of both sockets are equal. So, there's no any problem.
It's a slightly odd case, called a TCP "active/active open". A socket has been opened, bound to a local port and then connected to itself, by using connect() with its own address as the destination.
Nothing weird about that. It has a 1 in 63k chance of happening. What you won't see is * two* such ESTABLISHED* connections: that's impossible by the rules of TCP.

Resources