Skip to content
This repository has been archived by the owner on Aug 8, 2024. It is now read-only.

Commit

Permalink
upnp
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMarstonConnell committed Dec 8, 2022
1 parent 083e990 commit 218200e
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 3 deletions.
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ go 1.19

require (
github.com/cosmos/cosmos-sdk v0.45.11
github.com/jackalLabs/canine-chain v1.2.0-alpha.4
github.com/huin/goupnp v1.0.3
github.com/jackalLabs/canine-chain v1.2.0-alpha.7
github.com/julienschmidt/httprouter v1.3.0
github.com/rs/cors v1.8.2
github.com/rs/zerolog v1.27.0
Expand All @@ -15,6 +16,7 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tendermint/tendermint v0.34.23
github.com/wealdtech/go-merkletree v1.0.0
golang.org/x/sync v0.1.0
)

require (
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ=
github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
Expand All @@ -509,8 +511,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/jackalLabs/canine-chain v1.2.0-alpha.4 h1:1TBTnrPwOUrr089dyH1Fe0fS1Xy3ByHwSwGdzlPGCJ4=
github.com/jackalLabs/canine-chain v1.2.0-alpha.4/go.mod h1:Heucyt4Foa+ECilCHM1KDuoSkDESQ0R2O1vLk5iYTPU=
github.com/jackalLabs/canine-chain v1.2.0-alpha.7 h1:BvJmVHNFuhUPHOuIuT1xXgp7COPVfFlHcJd8RBa8xbM=
github.com/jackalLabs/canine-chain v1.2.0-alpha.7/go.mod h1:Heucyt4Foa+ECilCHM1KDuoSkDESQ0R2O1vLk5iYTPU=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
Expand Down Expand Up @@ -1071,6 +1073,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
26 changes: 26 additions & 0 deletions jprov/jprovd/provider_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func NetworkCmd() *cobra.Command {

cmd.AddCommand(
rpc.StatusCommand(),
GetIpCmd(),
)

return cmd
Expand Down Expand Up @@ -148,6 +149,31 @@ func GetBalanceCmd() *cobra.Command {
return cmd
}

func GetIpCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "ip",
Short: "Get provider ip address",
Long: `Get the external ip address this provider can be connected to.`,
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
client, err := server.PickRouterClient(cmd.Context())
if err != nil {
return err
}

externalIP, err := client.GetExternalIPAddress()
if err != nil {
return err
}
fmt.Printf("%s:3333\n", externalIP)

return nil
},
}

return cmd
}

func GetAddressCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "address",
Expand Down
1 change: 1 addition & 0 deletions jprov/server/file_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ func StartFileServer(cmd *cobra.Command) {
ctx := utils.GetServerContextFromCmd(cmd)

go postProofs(cmd, db, &q, ctx)
go NatCycle(cmd.Context())
go q.StartListener(cmd)
go q.CheckStrays(cmd, db)

Expand Down
136 changes: 136 additions & 0 deletions jprov/server/nat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package server

import (
"context"
"errors"
"fmt"
"net"
"time"

"github.com/JackalLabs/jackal-provider/jprov/types"
"github.com/huin/goupnp/dcps/internetgateway2"
"golang.org/x/sync/errgroup"
)

func GetLocalIP() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
return ""
}
for _, address := range addrs {
// check the address type and if it is not a loopback the display it
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String()
}
}
}
return ""
}

type RouterClient interface {
AddPortMapping(
NewRemoteHost string,
NewExternalPort uint16,
NewProtocol string,
NewInternalPort uint16,
NewInternalClient string,
NewEnabled bool,
NewPortMappingDescription string,
NewLeaseDuration uint32,
) (err error)

GetExternalIPAddress() (
NewExternalIPAddress string,
err error,
)
}

func PickRouterClient(ctx context.Context) (RouterClient, error) {
tasks, _ := errgroup.WithContext(ctx)
// Request each type of client in parallel, and return what is found.
var ip1Clients []*internetgateway2.WANIPConnection1
tasks.Go(func() error {
var err error
ip1Clients, _, err = internetgateway2.NewWANIPConnection1Clients()
return err
})
var ip2Clients []*internetgateway2.WANIPConnection2
tasks.Go(func() error {
var err error
ip2Clients, _, err = internetgateway2.NewWANIPConnection2Clients()
return err
})
var ppp1Clients []*internetgateway2.WANPPPConnection1
tasks.Go(func() error {
var err error
ppp1Clients, _, err = internetgateway2.NewWANPPPConnection1Clients()
return err
})

if err := tasks.Wait(); err != nil {
return nil, err
}

// Trivial handling for where we find exactly one device to talk to, you
// might want to provide more flexible handling than this if multiple
// devices are found.
switch {
case len(ip2Clients) == 1:
return ip2Clients[0], nil
case len(ip1Clients) == 1:
return ip1Clients[0], nil
case len(ppp1Clients) == 1:
return ppp1Clients[0], nil
default:
return nil, errors.New("multiple or no services found")
}
}

func NatCycle(ctx context.Context) {
for {

ip := GetLocalIP()
err := GetIPAndForwardPort(ctx, ip)
if err != nil {
fmt.Println(err)
}

time.Sleep(time.Second * 3600)

}
}

func GetIPAndForwardPort(ctx context.Context, internalIp string) error {
client, err := PickRouterClient(ctx)
if err != nil {
return err
}

_, err = client.GetExternalIPAddress()
if err != nil {
return err
}

return client.AddPortMapping(
"",
// External port number to expose to Internet:
3333,
// Forward TCP (this could be "UDP" if we wanted that instead).
"TCP",
// Internal port number on the LAN to forward to.
// Some routers might not support this being different to the external
// port number.
3333,
// Internal address on the LAN we want to forward to.
internalIp,
// Enabled:
true,
// Informational description for the client requesting the port forwarding.
types.AppName,
// How long should the port forward last for in seconds.
// If you want to keep it open for longer and potentially across router
// resets, you might want to periodically request before this elapses.
3600,
)
}
2 changes: 2 additions & 0 deletions jprov/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

const MaxFileSize = 32 << 30

const AppName = "jprovd"

type IndexResponse struct {
Status string `json:"status"`
Address string `json:"address"`
Expand Down

0 comments on commit 218200e

Please sign in to comment.