Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
go-libp2p
Commits
33a944bc
Commit
33a944bc
authored
Jan 24, 2015
by
Juan Batiz-Benet
Browse files
p2p/nat: upnp + pmp
parent
382daf3d
Changes
1
Hide whitespace changes
Inline
Side-by-side
nat/nat.go
0 → 100644
View file @
33a944bc
package
nat
import
(
"fmt"
"strconv"
"strings"
"time"
ma
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
manet
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
nat
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/fd/go-nat"
goprocess
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
eventlog
"github.com/jbenet/go-ipfs/thirdparty/eventlog"
)
var
log
=
eventlog
.
Logger
(
"nat"
)
const
MappingDuration
=
time
.
Second
*
60
func
DiscoverGateway
()
nat
.
NAT
{
nat
,
err
:=
nat
.
DiscoverGateway
()
if
err
!=
nil
{
log
.
Debug
(
"DiscoverGateway error:"
,
err
)
return
nil
}
addr
,
err
:=
nat
.
GetDeviceAddress
()
if
err
!=
nil
{
log
.
Debug
(
"DiscoverGateway address error:"
,
err
)
}
else
{
log
.
Debug
(
"DiscoverGateway address:"
,
addr
)
}
return
nat
}
type
Mapping
interface
{
NAT
()
nat
.
NAT
Protocol
()
string
InternalPort
()
int
ExternalPort
()
int
}
type
mapping
struct
{
// keeps republishing
nat
nat
.
NAT
proto
string
intport
int
extport
int
proc
goprocess
.
Process
}
func
(
m
*
mapping
)
NAT
()
nat
.
NAT
{
return
m
.
nat
}
func
(
m
*
mapping
)
Protocol
()
string
{
return
m
.
proto
}
func
(
m
*
mapping
)
InternalPort
()
int
{
return
m
.
intport
}
func
(
m
*
mapping
)
ExternalPort
()
int
{
return
m
.
extport
}
// NewMapping attemps to construct a mapping on protocl and internal port
func
NewMapping
(
nat
nat
.
NAT
,
protocol
string
,
internalPort
int
)
(
Mapping
,
error
)
{
log
.
Debugf
(
"Attempting port map: %s/%d"
,
protocol
,
internalPort
)
eport
,
err
:=
nat
.
AddPortMapping
(
protocol
,
internalPort
,
"http"
,
MappingDuration
)
if
err
!=
nil
{
return
nil
,
err
}
m
:=
&
mapping
{
nat
:
nat
,
proto
:
protocol
,
intport
:
internalPort
,
extport
:
eport
,
}
m
.
proc
=
goprocess
.
Go
(
func
(
worker
goprocess
.
Process
)
{
for
{
select
{
case
<-
worker
.
Closing
()
:
return
case
<-
time
.
After
(
MappingDuration
/
3
)
:
eport
,
err
:=
m
.
NAT
()
.
AddPortMapping
(
protocol
,
internalPort
,
"http"
,
MappingDuration
)
if
err
!=
nil
{
log
.
Warningf
(
"failed to renew port mapping: %s"
,
err
)
continue
}
if
eport
!=
m
.
extport
{
log
.
Warningf
(
"failed to renew same port mapping: ch %d -> %d"
,
m
.
extport
,
eport
)
}
}
}
})
return
m
,
nil
}
func
(
m
*
mapping
)
Close
()
error
{
return
m
.
proc
.
Close
()
}
func
MapAddr
(
n
nat
.
NAT
,
maddr
ma
.
Multiaddr
)
(
ma
.
Multiaddr
,
error
)
{
if
n
==
nil
{
return
nil
,
fmt
.
Errorf
(
"no nat available"
)
}
ip
,
err
:=
n
.
GetExternalAddress
()
if
err
!=
nil
{
return
nil
,
err
}
ipmaddr
,
err
:=
manet
.
FromIP
(
ip
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error parsing ip"
)
}
network
,
addr
,
err
:=
manet
.
DialArgs
(
maddr
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"DialArgs failed on addr:"
,
maddr
.
String
())
}
switch
network
{
case
"tcp"
,
"tcp4"
,
"tcp6"
:
network
=
"tcp"
case
"udp"
,
"udp4"
,
"udp6"
:
network
=
"udp"
default
:
return
nil
,
fmt
.
Errorf
(
"transport not supported by NAT: %s"
,
network
)
}
port
:=
strings
.
Split
(
addr
,
":"
)[
1
]
intport
,
err
:=
strconv
.
Atoi
(
port
)
if
err
!=
nil
{
return
nil
,
err
}
m
,
err
:=
NewMapping
(
n
,
"tcp"
,
intport
)
if
err
!=
nil
{
return
nil
,
err
}
tcp
,
err
:=
ma
.
NewMultiaddr
(
fmt
.
Sprintf
(
"/tcp/%d"
,
m
.
ExternalPort
()))
if
err
!=
nil
{
return
nil
,
err
}
maddr2
:=
ipmaddr
.
Encapsulate
(
tcp
)
log
.
Debugf
(
"NAT Mapping: %s --> %s"
,
maddr
,
maddr2
)
return
maddr2
,
nil
}
func
MapAddrs
(
addrs
[]
ma
.
Multiaddr
)
[]
ma
.
Multiaddr
{
nat
:=
DiscoverGateway
()
var
advertise
[]
ma
.
Multiaddr
for
_
,
maddr
:=
range
addrs
{
maddr2
,
err
:=
MapAddr
(
nat
,
maddr
)
if
err
!=
nil
||
maddr2
==
nil
{
log
.
Debug
(
"failed to map addr:"
,
maddr
,
err
)
continue
}
advertise
=
append
(
advertise
,
maddr2
)
}
return
advertise
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment