mirror of https://github.com/poanetwork/gecko.git
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package nat
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/jackpal/gateway"
|
|
|
|
natpmp "github.com/jackpal/go-nat-pmp"
|
|
)
|
|
|
|
var (
|
|
pmpClientTimeout = 500 * time.Millisecond
|
|
)
|
|
|
|
// natPMPClient adapts the NAT-PMP protocol implementation so it conforms to
|
|
// the common interface.
|
|
type pmpRouter struct {
|
|
client *natpmp.Client
|
|
}
|
|
|
|
func (pmp *pmpRouter) MapPort(
|
|
networkProtocol string,
|
|
newInternalPort uint16,
|
|
newExternalPort uint16,
|
|
mappingName string,
|
|
mappingDuration time.Duration) error {
|
|
protocol := string(networkProtocol)
|
|
internalPort := int(newInternalPort)
|
|
externalPort := int(newExternalPort)
|
|
// go-nat-pmp uses seconds to denote their lifetime
|
|
lifetime := int(mappingDuration / time.Second)
|
|
|
|
_, err := pmp.client.AddPortMapping(protocol, internalPort, externalPort, lifetime)
|
|
return err
|
|
}
|
|
|
|
func (pmp *pmpRouter) UnmapPort(
|
|
networkProtocol string,
|
|
internalPort uint16,
|
|
_ uint16) error {
|
|
protocol := string(networkProtocol)
|
|
internalPortInt := int(internalPort)
|
|
|
|
_, err := pmp.client.AddPortMapping(protocol, internalPortInt, 0, 0)
|
|
return err
|
|
}
|
|
|
|
func (pmp *pmpRouter) ExternalIP() (net.IP, error) {
|
|
response, err := pmp.client.GetExternalAddress()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return response.ExternalIPAddress[:], nil
|
|
}
|
|
|
|
// go-nat-pmp does not support port mapping entry query
|
|
func (pmp *pmpRouter) GetPortMappingEntry(externalPort uint16, protocol string) (
|
|
string, uint16, string, error) {
|
|
return "", 0, "", fmt.Errorf("port mapping entry not found")
|
|
}
|
|
|
|
func getPMPRouter() *pmpRouter {
|
|
gatewayIP, err := gateway.DiscoverGateway()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
pmp := &pmpRouter{natpmp.NewClientWithTimeout(gatewayIP, pmpClientTimeout)}
|
|
if _, err := pmp.ExternalIP(); err != nil {
|
|
return nil
|
|
}
|
|
|
|
return pmp
|
|
}
|