Returned UDP packets lacking port and fail to arrive - sockets

Golang application with a client and server.
Server uses net.ListenUDP -- client also uses net.ListenUDP, connects to server and sends a packet with conn.WriteToUDP with the server address.
Server receives the packet with ReadFromUDP and grabs the return address. Using this return address, it then sends a large number of packets back to the client.
When running both client and server on local machine, this works perfectly. Using Wireshark I can inspect the UDP packets and see that they contain the source and destination ports - and in the application I can see that they arrive and my various checksum tests show the data is accurate.
I then moved the server off site to a remote machine. The application stops working. I can successfully send the first message from the client to server - this is received just fine. The server sends the response back 'toward' the client - but the client never receives them.
Using Wireshark, I can see that the packets do arrive back on the local machine with the correct IP address. It appears that my network router has performed NAT on the outgoing packets - and has correctly re-addressed response packets to the internal IP.. BUT there is no port.
So I have UDP packets arriving on the correct machine, but no port - so the client application does not receive them. Application times out on ReadFromUDP.
I don't know if it is relevant, but on local machine, Wireshark labels the packets as BT-uTP Utorrent packets. When they come in from remote server, this is what I see in Wireshark - note the lack of Port.
Any thoughts how I can solve this. I didn't think this was a UDP hole punching problem because although I am establishing a connection across a NAT it is with a server not a peer.

This packet is fragmented, You can see this under Internet Protocol Version 4 > Flags.
If you look at the frame as shown on the bottom of the picture you provided you should see the ports.
net.ListenUDP doesn't appear to support fragmentation at the socket level.
Do you have a PPPoe connection? You may need to reduce your packet size being sent by 8 bytes or change the MTU on the routers external interface of the remote side. You may also need to change the local routers MTU if it's on a PPPoe interface.

Related

How to reserve tcp source port on linux?

I'm working on simple traffic tunneling solution (Linux).
Client side creates tun interface, routes all traffic on it, packages all arrived packets and sends to the server side via udp or tcp connection.
Server side expected to work like NAT. Change source ip address, source port (for tcp/udp) put packet on external network interface via sock_raw, listen for response via sock_raw, keep map of original-source-port <-> replaced-source-port and send responses back to the client.
The question is: how should I choose replaced-source-port ? OS chooses them from ephemeral ports. I can't choose it by myself, it would cause conflicts. OS kernel chooses port after I send packet via sock_raw and I have no chance to build original-source-port <-> replaced-source-port map. Even if I choose port by myself – OS kernel will reply with tcp rst to all incoming tcp packets with dst port not associated with particular app.
P.S. I'm not sure on the overall solution for tunneling too. Your suggestions would be highly appreciated.

capturing TCP packets flow

Problem statement:
Suppose a parent server is hosted on a machine IP: 1.1.1.1 and that server some time communicates with three different servers say A (1.1.1.2), B (1.1.1.3), C (1.1.1.4). Those servers may be database servers or any other servers.
Now from your browser you can send a http request to 1.1.1.1/somePage.htm, as a result some TCP packet will go to the server 1.1.1.1, and 1.1.1.1 can send and receive some TCP packets from A,B,C as well.
Aim is to get the information of all TCP packets from the browser machine, without installing any agent software in any servers.
One solution is we can write a code at the 1.1.1.1 server machine that will filter all the TCP packets with respect to respective IPs. But I don’t want that solution.
Is there any way to solve this issue? Is it possible to introduce new protocol for this? But server codes can’t be modified.
Does "any agent software" includes something like Wireshark? Usually the way to look at all datagrams received is by using a sniffer like Wireshark or you can use tcpdump in Linux servers.
You can also use Netfilter to handle received packets in the server an take certain actions on them.
If all the above is included in what you don't want to do the only alternative I see is to add another server in the middle between the browser and the web server (or between the server and a load balancer if you have a load balancer) that acts only as a router or bridge. In that machine you can inspect and filter TCP segments with all the available tools.

Ethernet not getting braodcast packets

I'm working on 2.6.15 kernel running on a cisco IPTV. When the box is coming up, the DHCP client hangs up. The reason for this is that the DHCP client does not get fetch the broadcasted DHCP offer message.
When I read /proc/net/dev file, it shows that ethernet device (eth0) has not received any packet. I then ran tcpdump on the box and it also shows that no packet is been received on the ethernet interface.
Then I ran wireshark on the test PC (on which DHCP server is running), it shows that a DHCP offer message is broadcasted by the DHCP server.
This DHCP client and server are working fine with other boxes so there are less chances that these programs have any issues. There must be an issue in the ethernet drivers.
I'm really confused. How should I proceed to this problem. Please help me.
Maybe you can start by checking whether the DHCP client is sending out a discovery.
The DHCP handshake goes like this:
client discovery,
server offer,
client request,
server ack
(Wikipedia has the steps of DHCP)
The next thing you can check any DHCP related settings on the router.
Is the DHCP client on the same subnet/vlan as the server? If not, would the router need a certain configuration to relay to/from the DHCP server subnet/vlan?

Error when using two different user agents

I have 2 sip clients on the same computer.
Both of them is registering to a server that is running on port 5060.
For the first client the UDP is on port 5060 and for the other is 5061. When I come from one client to another, after the ringing part i receive the error:
only one usage of each socket address is normally permited.
Got any ideas why I got this error?
Your server and client are both trying to use port 5060, hence the error message. Change the first client to use 5062 or something else.
Also, 5061 is normally used for secured SIP (normal listening port + 1 in the proxy/server). Do not use it for the second client.
It means you're clients are both trying to claim the same socket for the communication channel, or the server is trying to reclaim the socket given to client A, to reuse it for client B.
The software handeling the socket, should be smart enough to rely on the OS to assign port numbers instead of hardcoding the port numbers in the code, this is a 100% guarantee for socket issues.

Communication protocols in UDP

After many hours, I have discovered that the given udp server needs the following steps for a successful communication:
1- Send "Start Message" on a given port
2- Wait to receive from server on any port
3- Then the port dedicated to you to send further data to the server equals the port you have received on it + 1
So I am asking if this kind is a known protocol/handshaking, or it is only special to this server??
PS: All above communication were in udp sockets in C#
PS: Related to a previous question: About C# UDP Sockets
Thanks
There's no special "handshake" for UDP -- each UDP service, if it needs one, specifies its own. Usually, though, a server doesn't expect the client to be able to listen on all of its ports simultaneously. If you mean that the client expects a message from any port on the server, to the port the client sent the start message from, then that makes a lot more sense -- and is very close to how TFTP works. (The only difference i'm seeing so far, is that TFTP doesn't do the "+ 1".)
The server is, effectively, listening on a 'well known port' and then switching subsequent communications to a dedicated port per client. Requiring the client to send to the port + 1 is a little strange
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 5050
Client 192.168.0.1 - port 12121 <------------------------ Server 192.168.0.2 - port 23232
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 23232 + 1
<------------------------ Server 192.168.0.2 - port 23232
------------------------> Server 192.168.0.2 - port 23232 + 1
The server probably does this so that it doesn't have to demultiplex the inbound client data based on the client's address/port. Doing it this way is a little more efficient (generally) and also has some advantages, depending on the design of the server, as on the server there's a 'dedicated' socket for you which means that if they're doing overlapped I/O then the socket stays the same for the whole period of communications with you which can make it easier and more efficient to associate data with the socket (this way they can probably avoid any lookups or locking to process each datagram). Anyway, enough of that (see here, if you want to know why I do it that way).
From your point of view as a client (and I'm assuming async sockets here) you need to first Bind() your local socket (just use INADDR_ANY and 0 to allow the OS to pick the port for you) then issue a RecvFrom() on the socket (so there's no race between you sending data to the server on this socket and it sending you data back before you issue a recv). Then issue a SendTo() to the 'well known port' of the server. The server will then send you back some data and your RecvFrom() will return you the data and the address that the server sent to you from. You can then take that address, add one to the port, store that address and from then on issue SendTo()s to that new sending address whilst continuing to issue RecvFrom()s for reading the server's data; or you could do something clever with Connect() to bind the remote end of the socket to the server's 'send to address' and simply use Write() and RecvFrom() from then on.