Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
8d8b42f9be |
1 changed files with 18 additions and 1 deletions
|
@ -70,8 +70,17 @@ module NatPMP
|
|||
def initialize(@gateway_ip : String, autoconnect : Bool = true)
|
||||
# The specification is IPV4 only!
|
||||
@socket = UDPSocket.new(Socket::Family::INET)
|
||||
# A given host may have more than one independent
|
||||
# NAT-PMP client running at the same time, and address announcements
|
||||
# need to be available to all of them. Clients should therefore set
|
||||
# the SO_REUSEPORT option or equivalent in order to allow other
|
||||
# processes to also listen on port 5350.
|
||||
@socket.reuse_port = true
|
||||
@socket.reuse_address = true
|
||||
# Additionally, implementers
|
||||
# have encountered issues when one or more processes on the same device
|
||||
# listen to port 5350 on *all* addresses. Clients should therefore
|
||||
# bind specifically to 224.0.0.1:5350, not to 0.0.0.0:5350.
|
||||
@socket.bind 5350
|
||||
if autoconnect
|
||||
connect()
|
||||
|
@ -79,6 +88,7 @@ module NatPMP
|
|||
end
|
||||
|
||||
def connect
|
||||
# @socket.join_group(Socket::IPAddress.new("224.0.0.1", 5351))
|
||||
@socket.connect(@gateway_ip, 5351)
|
||||
end
|
||||
|
||||
|
@ -99,6 +109,11 @@ module NatPMP
|
|||
@socket.receive(msg)
|
||||
break
|
||||
rescue IO::TimeoutError
|
||||
# If no
|
||||
# NAT-PMP response is received from the gateway after 250 ms, the
|
||||
# client retransmits its request and waits 500 ms. The client SHOULD
|
||||
# repeat this process with the interval between attempts doubling each
|
||||
# time.
|
||||
@socket.read_timeout = @socket.read_timeout.not_nil!*2
|
||||
next
|
||||
rescue
|
||||
|
@ -112,6 +127,9 @@ module NatPMP
|
|||
result_code = decode_msg(UInt16, msg[2..3])
|
||||
epoch = decode_msg(UInt32, msg[4..7])
|
||||
|
||||
# If the result code is non-zero, the value of the External
|
||||
# IPv4 Address field is undefined (MUST be set to zero on transmission,
|
||||
# and MUST be ignored on reception).
|
||||
if result_code != 0
|
||||
ip_address = nil
|
||||
else
|
||||
|
@ -120,7 +138,6 @@ module NatPMP
|
|||
return vers, op, result_code, epoch, ip_address
|
||||
end
|
||||
|
||||
# https://datatracker.ietf.org/doc/html/rfc6886#section-3.3
|
||||
def request_mapping(internal_port : UInt16, external_port : UInt16, operation : UInt8, lifetime : UInt32 = 7200)
|
||||
request = MappingPacket.new(internal_port, external_port, lifetime, operation).to_slice
|
||||
msg = Bytes.new(16)
|
||||
|
|
Loading…
Reference in a new issue