I do UDP hole punching using the following method: I have a lobby server L, and two clients A and B behind a (shared) NAT.
Now, A and B are running on the same machine. They both send a datagram to server L.
Server L tells both A and B the IP+PORT of the other.
Note that the IPs of A and B that the server sees are identical, but the ports are different, as expected.
Then A and B send a datagram to each other, using the server provided addr+port.
Yet, their datagrams to each other never arrive.
My question: does UDP hole punching work if both clients are on the same machine? What if they are just on the same LAN, behind the same NAT?
NOTE: I tried to lower the strictness of my router, but Archer C7 does not seem to have a selection for Cone/Symmetric/Asymmetric unfortunately. I did switch off Stateful Packet Inspection.
UPDATE: When I try sending punch datagrams, I do see this come by over the network device:
ICMP dest unrch (port)
UPDATE: stunclient output:
$ stunclient --mode full stunserver.stunprotocol.org
Binding test: success
Local address: 10.0.1.2:49703
Mapped address: 209.161.250.218:49703
Behavior test: success
Nat behavior: Endpoint Independent Mapping
Filtering test: success
Nat filtering: Address and Port Dependent Filtering
Related
I'm using GCP like in the following schema:
TCP balancer -> backend-service -> MIG(my app) with auto scaling.
"My app" accepts commands on a TCP port (A) and sends notifications on another TCP port(B) for subscriber.
I'm running my tests against TCP LB's IP - my tests connect to port B on a startup(i.e. one of instances of "my app") and also my tests make a connection to port A for each test.
i.e. I've faced with a case when port A and port B are terminated/connected to different hosts.
I am not sure how to circumvent this case.
I have mitigated the issue using --session-affinity=CLIENT_IP for backend-services configuration, I.e. all connections from one IP are directed to the same target.
I have installed the TURN server everything in the server code is working fine. no error in the log file. only a warning stating
0: WARNING: I cannot support STUN CHANGE_REQUEST functionality because only one IP address is provided
but the TURN server running on the server.
here is what shows when I check lsof -i :3478
turnserve 999 root 15u IPv4 446811411 0t0 TCP domain.com:stun (LISTEN)
turnserve 999 root 23u IPv4 446811417 0t0 TCP domain:stun (LISTEN)
turnserve 999 root 24u IPv4 446810998 0t0 UDP domain.com:stun
turnserve 999 root 25u IPv4 446810999 0t0 UDP domain.com:stun
when I check STUN in Trickle ICE it throws an errors
The server stun:xxx.xxx.xxx.xxx:3478 returned an error with code=701:
STUN server address is incompatible.
The server stun:xxx.xxx.xxx.xxx:3478 returned an error with code=701:
STUN allocate request timed out.
what's going wrong in this.
Thank you
I think that 701 error is a more generic connectivity error that Trickle ICE uses to indicate it didn't get a binding response back. Run stunclient your.stun.ip.address with the command line tools at www.stunprotocol.org to see if your STUN service is accessible from the outside world.
STUN technically requires being hosted on a device with two IP addresses and two ports. It's typically a command line parameter to specify which IP addresses the server should listen on. But most server implementations can operate on a host with a single IP address.
The second IP address and port on the server is used for STUN client filtering tests to detect what type of NAT is in effect. The client sends a binding request on the server's primary ip and port, but with a change request attribute to have the server respond from the alternate IP address or port. More often than not, this binding request with a change-request attribute fails since NATs will not forward traffic from the other IP/port.
The filtering test is useful for logging what type of NAT the client is on. So that failed connections can be debugged and that success/failure metrics can be correlated to NAT type.
Since most ICE implementations will exchange all available address candidates (local, mapped, and relay), the filtering test isn't very or useful to connectivity establishment.
I'm surprised Trickle ICE is giving you an error. I didn't think WebRTC ever used the changer-request attribute. I just did a Wireshark trace of a Trickle ICE session to stunserver.stunprotocol.org. I don't see the webrtc client setting the change-request attribute in either of the two binding requests it makes.
More details in RFC 5780 Section 3.2
In macOS, I just do so:
> brew install stuntman
when it done
> stunclient stunserver.stunprotocol.org
Binding test: success
Local address: 198.18.0.1:54898
Mapped address: 210.0.158.130:56750
To specify port, just like this:
> stunclient stunserver.stunprotocol.org 3478
Binding test: success
Local address: 198.18.0.1:63061
Mapped address: 210.0.158.130:37126
Have fun!
I am trying to set up a STUN/TURN server on my local computer for a webrtc application of me. I decided to use coturn. Note that my server is running behind a NAT.
So i fired up my Ubuntu VM and installed it. After reading through the wiki I got it working, atleast on my local network. For testing purposes, i use this site. Therefore, when i try it there with 192.168.178.25:3478, it works. When i try it with "public-ip":3478, it doesnt.
This told me, it is working locally and it should be a port/NAT issue. What i did:
1) I set the VM to Bridging
2) I opened the port 3478 on my router. To test if this is really working, i used telnet on a remote machine and it worked. Another test was that i set up a quick apache server on my local machine on port 3478 and it could be accessed from the outside. This told me that there is, or should be, not port/NAT issue and my turn server should be working.
Any ideas?
I am running my server with the following command:
"sudo turnserver -X "public-ip" -listening-port=3478 -v
The turnserver.conf looks something like this:
fingerprint
realm="myRealm"
lt-cred-mech
user=test:test
As telnet and apache server are both working, i am pretty sure i have a configuration issue. I basically spent the weekend trying and im really lost on what could be wrong.
Thanks for any help!
From the documentation of turnserver
-X, --external-ip <public-ip>[/private-ip] TURN Server public/private address mapping, if the server is behind NAT. In that situation, if a -X is used in form "-X " then that ip will be reported as relay IP address of all allocations. This scenario works only in a simple case when one single relay address is to be used, and no CHANGE_REQUEST STUN functionality is required. That single relay address must be mapped by NAT to the 'external' IP. The "external-ip" value, if not empty, is returned in XOR-RELAYED-ADDRESS field. For that 'external' IP, NAT must forward ports directly (relayed port 12345 must be always mapped to the same 'external' port 12345). In more complex case when more than one IP address is involved, that option must be used several times, each entry must have form "-X ", to map all involved addresses. CHANGE_REQUEST NAT discovery STUN functionality will work correctly, if the addresses are mapped properly, even when the TURN server itself is behind A NAT. By default, this value is empty, and no address mapping is used.
So, it is not enough that you expose only the listening port from the inside LAN to the public network but all ports that you are going to use to relay. Please, note what is said in the same documentation:
--min-port <port> Lower bound of the UDP port range for relay endpoints allocation. Default value is 49152, according to RFC 5766.
--max-port <port> Upper bound of the UDP port range for relay endpoints allocation. Default value is 65535, according to RFC 5766.
You should choose a range of ports in the server, configure with them the options --min-port and --max-port and create a NAT rule to expose those ports to the public side of the router without change.
I was looking for an answer on my question on google and also here, but a didn't find a proper answer.
So here is the context:
I have a software running on some server (without firewall) in one subnet.
There is another software running on some PC in a different subnet.
Both subnets are connected to a gateway server. All computers are running CentOS or RHEL.
On the gateway server, there is a firewall, preventing multicast traffic from leaving the one subnet and allow clients from outside to connect to computers inside this subnet. Therefore xinetd is used. The computer from outside needs to send a packet to a specific port, the computer on the inside answers to another specific port depending on the sender. So there is no need for the gateway to keep track of sender-receiver relations. It just needs to forward UDP on specific ports to specific computers from one subnet to another.
So I added one service in /etc/services (for one direction):
udp-gateway 6000/udp
And created the according configuration file in /etc/xinetd.d/gateway like:
service udp-gateway
{
disable = no
socket_type = dgram
protocol = udp
wait = no
user = root
redirect = 192.168.1.1 6000 #Server inside the 192.168.1.0 subnet
}
Now the problem is, that the server doesn't open an UDP-port to listen on ('netstat -nulp' says). When I change the protocol to TCP and the socket_type to stream, it works. But I need this for UDP.
Is it possible that this is not possible for UDP? Or is netstat just not showing the ports? Or is my xinetd-configuration missing something?
Thanks in advance, every hint is appreciated.
Benny
redirect = 192.168.1.1 6000 #Server inside the 192.168.1.0 subnet
from the man page of xinetd:
redirect
Allows a tcp service to be redirected to another host.
This means usage of redirect for udp is not possible. And I don't see any other way to do this with xinetd.
how can i do NAT tunnel UDP hole punching in java?
because of this, the A and B computer behind the different NAT can not receice the UDP packs which they send to each other.....
how can i solve this?
You need a server S with a public IP address. A and B should open a connection to S. This will open an UDP hole in the NAT. Then S can read the NAT translated address/port for A and B. Then S can send back this information to A and B who can start communicating directly on each other's open TCP port.