I’m trying to implement Hole Punching using “builtins.scripts.socket”.
I’ve changed a bit Defnet “tcp_server” and “tcp_client”, implemented Stun client, but Hole Punching doesn’t work.
First of all I’m connecting to Stun server and taking my remote Ip and remote Port. I’m setting option “reuseaddr” and “settimeout(0)” for the Stun socket which I’m saving. Then I’m getting local Port from the Stun socket with “getsockname()” and running my Server with this local Port (port is reusable).
When on another machine I’m doing all the steps, but instead of Server creation I’m trying to create Client on top of Stun socket and connect it to my Server’s remote Ip and Port. I’m using “socket.connect()” for this.
I think I’m tried all of variations of “socket.connect()”, but nothing helps. For example, “socket.connect(remote_ip, remote_port)” or “socket.connect(remote_ip, remote_port, nil, local_port)” just hangs, “socket.connect(remote_ip, remote_port, “*”, local_port)” causes “address already in use” error. Sometimes I had “connection refused” error.
Hole punching is basically a method for revealing correct forwarding ports. So you send something to somewhere, it then relays the port to somewhere else who then tries to connect to the first sender via that port. It can be used for UDP and TCP but does not work under all network situations.
@cnaize What exactly are you trying to do? Maybe there is a better way to get your connections working. You should post a small example project of what you are so far and what network setup you are testing under.
I need to connect directly two applications, one is server another is client. Any of them can be behind NAT. Maybe you know a better way?
Here is a code snippet. I tried it with two different networks and on “socket.connect” I had “connection refused” error or just application hang.
local tcp_server = require "defnet.tcp_server"
local socket = require "socket.socket"
local stun = require "modules.net.stun"
local skt_1, l_port_1, r_ip, r_port = stun.connect()
assert(skt_1)
print("STUN:", l_port_1, r_ip, r_port)
local server = tcp_server.create(l_port_1, function()
print("SERVER ON DATA")
end, function()
print("SERVER ON CONNECT")
end, function()
print("SERVER ON DISCONNECT")
end)
assert(server)
assert(server.start())
print("SERVER STARTED")
local skt_2, l_port_2 = stun.connect()
assert(skt_2)
local client, err = socket.connect(r_ip, r_port, nil, l_port_2)
assert(client, err)
server.update()
“modules.net.stun”:
M.connect()
...
local ok, err = pcall(function()
local skt, err = socket.connect(server_addr, server_port)
assert(skt, err)
stun.socket = skt
assert(stun.socket:setoption("reuseaddr", true))
assert(stun.socket:send(create_stun_request(stun)))
end)
if not ok then
stun.socket:close()
return nil, nil, nil, nil, err
end
local _, l_port = stun.socket:getsockname()
return stun.socket, l_port, parse_stun_response(stun)
end