You don't need STUN. This is just the noob getting excited about stuff he read online that he doesn't actually understand.
Of course STUN is not something necessary, it's just an option to check the NAT type. Not a big deal as i said.
You don't need to reverse the NAT address translation, just allow NAT to function the way it is designed.
You only need to send packets from host before game starts.
You only need to send packets to people in the channel.
That will be a plan for future, as a 1-st step it's easier to send packets all the time.
And it causes disconnect, no idea why, but that's unacceptable behavior even if i sent them in wrong time and to wrong ips.
I think I see your problem ! I think it is because you are sending traffic to the REMOTE port. The "remote port" variable should actually be your LOCAL port, not remote port.
I know its confusing but there is a reason -- you need to send traffic to the remote host:local port, that way the connection is opened for the remote host to reply on your LOCAL port. They dont need to reply on their own port. Also, the traffic we are sending them we dont care that they dont ever receive it, we are just tricking out own firewall (not theirs) make sense? Try again with that and let me know if it works
I didn't understan your logic, well:
my Game Data Port is 6113, your Game Data Port is 6112, my external ip is 1.1.1.1, your external ip is 2.2.2.2
I host the game behind NAT on my local computer internal ip 192.168.1.1:6113, i need to make you connect from your 2.2.2.2:6112 to my 1.1.1.1:6113.
How to do that? I apply lat trick: send UDP packet to the opposite side: from my 192.168.1.1:6113 to 2.2.2.2:6112, right?
Then my (full cone) NAT translates it: you receive packet from my 1.1.1.1:6113 to 2.2.2.2:6112. Also my router keeps temporary rule: to wait answers to that packet.
When you try to connect from your 2.2.2.2:6112 to my 1.1.1.1:6113, my router thinks it's the answer to that packet and NAT's it to my internal host: 192.168.1.1:6113, right?
So, you offer to send packet from my 192.168.1.1:6113 to your 2.2.2.2:6113? Though your client listens on 2.2.2.2:6112? Looks senseless for me.
Another idea:
We open the socket: client.bind(('0.0.0.0', war2_client_port))
Also, war2 client opens the same socket.
Who will receive packets incoming to war2_client_port? Our script or war2? Who will be more lucky?
Maybe we should close our socket right after we sent our packets?
What do you think about that?
Not a guarantee (as we can get packets while sending packets), but should become much better as for me.
...
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.bind(('0.0.0.0', war2_client_port))
client.sendto("For the Alliance", (target_host, war2_remote_port))
client.close() # or how to write that on python, i don't know it's syntax
UPDATE:
just got that:
Socket close is not closing the socket immediately or something like that, it goes into the TIME_WAIT instead:
https://stackoverflow.com/questions/22549044/why-is-port-not-immediately-released-after-the-socket-closesThey say about SO_REUSEADDR, but that is not we need. Our task is not to catch even sinlge packet destined to war2.
How to do that? I'm not so good in network technologies. I'd say the proper way is to inject into war2 network functions. Or probably to listen our Game Data Port and copy all these traffic to war2 process (also, how to do that?)
UPDATE2:
additional info:
socket abort should guarantee to free the socket immediately. Depends on OS/language. Sometimes you have to set "linger off" or w/e and then repeat close.
Not sure if it's actual for UDP, maybe for TCP only.
Anyways, we have to control every socket function succeeded. In our situation you can never be sure your client.bind or sendto succeeded.
@AHB, can you add checking all the possible return errors in your code?
Something like:
try:
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except Exception as e:
print e
try:
client.bind(('0.0.0.0', war2_client_port))
except Exception as e:
print e
Fix the code plz, i'm not good in programming and don't know python at all.