rvsTuna

package module
v1.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2022 License: Apache-2.0 Imports: 42 Imported by: 1

README

TUNA 🐟

TUNA (Tunnel Using NKN for any Application) allows anyone to tunnel any network based services through NKN. Node will receive payment for tunneled traffic directly from user.

Note: UDP mode is still work in progress. Please use TCP-only services for now.

Build

Simply run make will do the work. The output binary name will be tuna.

Get Started

Either entry mode or exit mode will need a service definition file services.json. You can start by using services.json.example as template. The service file defines what services to use or provide, which ports a service uses, and various configurations like encryption.

Entry Mode

You will need a config file config.entry.json. You can start by using config.entry.json.example as template.

Start tuna in entry mode:

./tuna entry

Then you can start using configured services as if they're on your local machine (e.g. 127.0.0.1:30080 for HTTP proxy).

Exit Mode

You will need a config file config.exit.json. You can start by using config.exit.json.example as template.

Start tuna in exit mode:

./tuna exit

Then users can connect to your services through their tuna entry and pay you NKN based on bandwidth comsumption.

Reverse Entry Mode

Set reverse to true in config.entry.json and start tuna in entry mode. Then users can use your node as reverse proxy and pay you NKN based on bandwidth comsumption.

Reverse Exit Mode

Set reverse to true in config.exit.json and start tuna in exit mode. Then your service will be exposed to public network by reverse entry. Your node does not need to have public IP address or open port at all.

Config

Entry mode config config.entry.json:

  • services services you want to use
  • dialTimeout timeout for NKN node connection
  • udpTimeout timeout for UDP connections
  • nanoPayFee fee used for nano pay transaction
  • reverse should be used to provide reverse tunnel for those who don't have public IP
  • reverseBeneficiaryAddr Beneficiary address (NKN wallet address to receive rewards)
  • reverseTCP TCP port to listen for connections
  • reverseUDP UDP port to listen for connections
  • reversePrice price for reverse connections
  • reverseClaimInterval payment claim interval for reverse connections
  • reverseSubscriptionDuration duration for subscription in blocks
  • reverseSubscriptionFee fee used for subscription

Exit mode config config.exit.json:

  • beneficiaryAddr beneficiary address (NKN wallet address to receive rewards)
  • listenTCP TCP port to listen for connections
  • listenUDP UDP port to listen for connections
  • dialTimeout timeout for connections to services
  • udpTimeout timeout for UDP connections
  • claimInterval payment claim interval for connections
  • subscriptionDuration duration for subscription in blocks
  • subscriptionFee fee used for subscription
  • services services you want to provide
  • reverse should be used if you don't have public IP and want to use another server for accepting clients
  • reverseRandomPorts meaning reverse entry can use random ports instead of specified ones (useful when service has dynamic ports)
  • reverseMaxPrice max accepted price for reverse service, unit is NKN per MB traffic
  • reverseNanoPayFee nanoPay transaction fee for reverse service
  • reverseIPFilter reverse service IP address filter

Use as library

Most of them times you just need to run tuna entry/exit as a separate program together with the services, but you can also use tuna as a library. See cmd/entry.go and cmd/exit.go for examples.

Compiling to iOS/Android native library

This library is designed to work with gomobile and run natively on iOS/Android without any modification. You can use gomobile bind to compile it to Objective-C framework for iOS:

gomobile bind -target=ios -ldflags "-s -w" github.com/Mohsinsiddi/rvs-tuna github.com/nknorg/nkn-sdk-go github.com/nknorg/nkngomobile

and Java AAR for Android:

gomobile bind -target=android -ldflags "-s -w" github.com/Mohsinsiddi/rvs-tuna github.com/nknorg/nkn-sdk-go github.com/nknorg/nkngomobile

More likely you might want to write a simple wrapper uses tuna and compile it using gomobile.

It's recommended to use the latest version of gomobile that supports go modules.

Contributing

Can I submit a bug, suggestion or feature request?

Yes. Please open an issue for that.

Can I contribute patches?

Yes, we appreciate your help! To make contributions, please fork the repo, push your changes to the forked repo with signed-off commits, and open a pull request here.

Please sign off your commit. This means adding a line "Signed-off-by: Name " at the end of each commit, indicating that you wrote the code and have the right to pass it on as an open source patch. This can be done automatically by adding -s when committing:

git commit -s

Community

Documentation

Index

Constants

View Source
const (
	DefaultSubscriptionPrefix = "tuna_v1."
	DefaultReverseServiceName = "reverse"
)
View Source
const (
	TrafficUnit = 1024 * 1024
)

Variables

This section is empty.

Functions

func Close

func Close(conn io.Closer)

func ConnIDToPort

func ConnIDToPort(data []byte) uint16

func CreateRawMetadata

func CreateRawMetadata(
	serviceID byte,
	serviceTCP []uint32,
	serviceUDP []uint32,
	ip string,
	tcpPort uint32,
	udpPort uint32,
	price string,
	beneficiaryAddr string,
) []byte

func GetFavoriteSeedRPCServer

func GetFavoriteSeedRPCServer(path, filenamePrefix string, timeout int32) ([]string, error)

GetFavoriteSeedRPCServer wraps GetFavoriteSeedRPCServerContext with background context.

func GetFavoriteSeedRPCServerContext

func GetFavoriteSeedRPCServerContext(ctx context.Context, path, filenamePrefix string, timeout int32) ([]string, error)

GetFavoriteSeedRPCServerContext returns an array of node rpc address from favorite node file. Timeout is in unit of millisecond.

func LoadOrCreateAccount

func LoadOrCreateAccount(walletFile, passwordFile string) (*vault.Account, error)

func LoadPassword

func LoadPassword(path string) (string, error)

func ParseEncryptionAlgo

func ParseEncryptionAlgo(encryptionAlgoStr string) (pb.EncryptionAlgo, error)

func ParsePrice

func ParsePrice(priceStr string) (common.Fixed64, common.Fixed64, error)

func PortToConnID

func PortToConnID(port uint16) []byte

func ReadMetadata

func ReadMetadata(metadataString string) (*pb.ServiceMetadata, error)

func ReadVarBytes

func ReadVarBytes(reader io.Reader, maxMsgSize uint32) ([]byte, error)

func StartReverse

func StartReverse(config *EntryConfiguration, wallet *rvs.Wallet) error

func UpdateMetadata

func UpdateMetadata(
	serviceName string,
	serviceID byte,
	serviceTCP []uint32,
	serviceUDP []uint32,
	ip string,
	tcpPort uint32,
	udpPort uint32,
	price string,
	beneficiaryAddr string,
	subscriptionPrefix string,
	subscriptionDuration uint32,
	subscriptionFee string,
	subscriptionReplaceTxPool bool,
	client *rvs.MultiClient,
	closeChan chan struct{},
)

func WriteVarBytes

func WriteVarBytes(writer io.Writer, b []byte) error

Types

type Common

type Common struct {
	Service                        *Service
	ServiceInfo                    *ServiceInfo
	Wallet                         *rvs.Wallet
	Client                         *rvs.MultiClient
	DialTimeout                    int32
	SubscriptionPrefix             string
	Reverse                        bool
	ReverseMetadata                *pb.ServiceMetadata
	OnConnect                      *OnConnect
	IsServer                       bool
	GeoDBPath                      string
	DownloadGeoDB                  bool
	GetSubscribersBatchSize        int
	MeasureBandwidth               bool
	MeasureBandwidthTimeout        time.Duration
	MeasureBandwidthWorkersTimeout time.Duration
	MeasurementBytesDownLink       int32
	MeasureStoragePath             string
	MaxPoolSize                    int32

	sync.RWMutex
	// contains filtered or unexported fields
}

func NewCommon

func NewCommon(
	service *Service,
	serviceInfo *ServiceInfo,
	wallet *rvs.Wallet,
	client *rvs.MultiClient,
	seedRPCServerAddr []string,
	dialTimeout int32,
	subscriptionPrefix string,
	reverse, isServer bool,
	geoDBPath string,
	downloadGeoDB bool,
	getSubscribersBatchSize int32,
	measureBandwidth bool,
	measureBandwidthTimeout int32,
	measureBandwidthWorkersTimeout int32,
	measurementBytes int32,
	measureStoragePath string,
	maxPoolSize int32,
	sortMeasuredNodes func(types.Nodes),
	reverseMetadata *pb.ServiceMetadata,
) (*Common, error)

func (*Common) CreateServerConn

func (c *Common) CreateServerConn(force bool) error

func (*Common) GetConnected

func (c *Common) GetConnected() bool

func (*Common) GetMetadata

func (c *Common) GetMetadata() *pb.ServiceMetadata

func (*Common) GetNumActiveSessions

func (c *Common) GetNumActiveSessions() int

func (*Common) GetPaymentReceiver

func (c *Common) GetPaymentReceiver() string

func (*Common) GetPrice

func (c *Common) GetPrice() (common.Fixed64, common.Fixed64)

func (*Common) GetRemoteNknAddress

func (c *Common) GetRemoteNknAddress() string

func (*Common) GetServerTCPConn

func (c *Common) GetServerTCPConn(force bool) (net.Conn, error)

func (*Common) GetServerUDPConn

func (c *Common) GetServerUDPConn(force bool) (*net.UDPConn, error)

func (*Common) GetServerUDPReadChan

func (c *Common) GetServerUDPReadChan(force bool) (chan []byte, error)

func (*Common) GetServerUDPWriteChan

func (c *Common) GetServerUDPWriteChan(force bool) (chan []byte, error)

func (*Common) GetSessionsWaitGroup

func (c *Common) GetSessionsWaitGroup() *sync.WaitGroup

func (*Common) GetTCPConn

func (c *Common) GetTCPConn() net.Conn

func (*Common) GetTopPerformanceNodes

func (c *Common) GetTopPerformanceNodes(measureBandwidth bool, n int) (types.Nodes, error)

func (*Common) GetTopPerformanceNodesContext

func (c *Common) GetTopPerformanceNodesContext(ctx context.Context, measureBandwidth bool, n int) (types.Nodes, error)

func (*Common) GetUDPConn

func (c *Common) GetUDPConn() *net.UDPConn

func (*Common) SetConnected

func (c *Common) SetConnected(connected bool)

func (*Common) SetLinger

func (c *Common) SetLinger(t time.Duration)

SetLinger sets the behavior of Close when there is at least one active session. t = 0 (default): close all conn when tuna close. t < 0: tuna Close() call will block and wait for all sessions to close before closing tuna. t > 0: tuna Close() call will block and wait for up to timeout all sessions to close before closing tuna.

func (*Common) SetMetadata

func (c *Common) SetMetadata(metadata *pb.ServiceMetadata)

func (*Common) SetPaymentReceiver

func (c *Common) SetPaymentReceiver(paymentReceiver string) error

func (*Common) SetRemoteNknAddress

func (c *Common) SetRemoteNknAddress(nknAddr string)

func (*Common) SetServerTCPConn

func (c *Common) SetServerTCPConn(conn net.Conn)

func (*Common) SetServerUDPConn

func (c *Common) SetServerUDPConn(conn *net.UDPConn)

func (*Common) SetServerUDPReadChan

func (c *Common) SetServerUDPReadChan(udpReadChan chan []byte)

func (*Common) SetServerUDPWriteChan

func (c *Common) SetServerUDPWriteChan(udpWriteChan chan []byte)

func (*Common) StartUDPReaderWriter

func (c *Common) StartUDPReaderWriter(conn *net.UDPConn)

func (*Common) UpdateServerConn

func (c *Common) UpdateServerConn(remotePublicKey []byte) error

func (*Common) WaitSessions

func (c *Common) WaitSessions()

WaitSessions waits for sessions wait group, or until linger times out.

type EntryConfiguration

type EntryConfiguration struct {
	SeedRPCServerAddr                []string               `json:"seedRPCServerAddr"`
	Services                         map[string]ServiceInfo `json:"services"`
	DialTimeout                      int32                  `json:"dialTimeout"`
	UDPTimeout                       int32                  `json:"udpTimeout"`
	NanoPayFee                       string                 `json:"nanoPayFee"`
	MinNanoPayFee                    string                 `json:"minNanoPayFee"`
	NanoPayFeeRatio                  float64                `json:"nanoPayFeeRatio"`
	SubscriptionPrefix               string                 `json:"subscriptionPrefix"`
	Reverse                          bool                   `json:"reverse"`
	ReverseBeneficiaryAddr           string                 `json:"reverseBeneficiaryAddr"`
	ReverseTCP                       int32                  `json:"reverseTCP"`
	ReverseUDP                       int32                  `json:"reverseUDP"`
	ReverseServiceListenIP           string                 `json:"reverseServiceListenIP"`
	ReversePrice                     string                 `json:"reversePrice"`
	ReverseClaimInterval             int32                  `json:"reverseClaimInterval"`
	ReverseMinFlushAmount            string                 `json:"reverseMinFlushAmount"`
	ReverseServiceName               string                 `json:"reverseServiceName"`
	ReverseSubscriptionPrefix        string                 `json:"reverseSubscriptionPrefix"`
	ReverseSubscriptionDuration      int32                  `json:"reverseSubscriptionDuration"`
	ReverseSubscriptionFee           string                 `json:"reverseSubscriptionFee"`
	ReverseSubscriptionReplaceTxPool bool                   `json:"reverseSubscriptionReplaceTxPool"`
	GeoDBPath                        string                 `json:"geoDBPath"`
	DownloadGeoDB                    bool                   `json:"downloadGeoDB"`
	GetSubscribersBatchSize          int32                  `json:"getSubscribersBatchSize"`
	MeasureBandwidth                 bool                   `json:"measureBandwidth"`
	MeasureBandwidthTimeout          int32                  `json:"measureBandwidthTimeout"`
	MeasureBandwidthWorkersTimeout   int32                  `json:"measureBandwidthWorkersTimeout"`
	MeasurementBytesDownLink         int32                  `json:"measurementBytesDownLink"`
	MeasureStoragePath               string                 `json:"measureStoragePath"`
	MaxMeasureWorkerPoolSize         int32                  `json:"maxMeasureWorkerPoolSize"`
	SortMeasuredNodes                func(types.Nodes)      `json:"-"`
}

func DefaultEntryConfig

func DefaultEntryConfig() *EntryConfiguration

func MergedEntryConfig

func MergedEntryConfig(conf *EntryConfiguration) (*EntryConfiguration, error)

type ExitConfiguration

type ExitConfiguration struct {
	SeedRPCServerAddr              []string                   `json:"seedRPCServerAddr"`
	BeneficiaryAddr                string                     `json:"beneficiaryAddr"`
	ListenTCP                      int32                      `json:"listenTCP"`
	ListenUDP                      int32                      `json:"listenUDP"`
	DialTimeout                    int32                      `json:"dialTimeout"`
	UDPTimeout                     int32                      `json:"udpTimeout"`
	SubscriptionPrefix             string                     `json:"subscriptionPrefix"`
	SubscriptionDuration           int32                      `json:"subscriptionDuration"`
	SubscriptionFee                string                     `json:"subscriptionFee"`
	SubscriptionReplaceTxPool      bool                       `json:"subscriptionReplaceTxPool"`
	ClaimInterval                  int32                      `json:"claimInterval"`
	MinFlushAmount                 string                     `json:"minFlushAmount"`
	Services                       map[string]ExitServiceInfo `json:"services"`
	Reverse                        bool                       `json:"reverse"`
	ReverseRandomPorts             bool                       `json:"reverseRandomPorts"`
	ReverseMaxPrice                string                     `json:"reverseMaxPrice"`
	ReverseNanoPayFee              string                     `json:"reverseNanopayfee"`
	MinReverseNanoPayFee           string                     `json:"minReverseNanoPayFee"`
	ReverseNanoPayFeeRatio         float64                    `json:"reverseNanopayfeeRatio"`
	ReverseServiceName             string                     `json:"reverseServiceName"`
	ReverseSubscriptionPrefix      string                     `json:"reverseSubscriptionPrefix"`
	ReverseEncryption              string                     `json:"reverseEncryption"`
	GeoDBPath                      string                     `json:"geoDBPath"`
	DownloadGeoDB                  bool                       `json:"downloadGeoDB"`
	GetSubscribersBatchSize        int32                      `json:"getSubscribersBatchSize"`
	ReverseIPFilter                geo.IPFilter               `json:"reverseIPFilter"`
	ReverseNknFilter               filter.NknFilter           `json:"reverseNknFilter"`
	MeasureBandwidth               bool                       `json:"measureBandwidth"`
	MeasureBandwidthTimeout        int32                      `json:"measureBandwidthTimeout"`
	MeasureBandwidthWorkersTimeout int32                      `json:"measureBandwidthWorkersTimeout"`
	MeasurementBytesDownLink       int32                      `json:"measurementBytesDownLink"`
	MeasureStoragePath             string                     `json:"measureStoragePath"`
	MaxMeasureWorkerPoolSize       int32                      `json:"maxMeasureWorkerPoolSize"`
	SortMeasuredNodes              func(types.Nodes)          `json:"-"`
}

func DefaultExitConfig

func DefaultExitConfig() *ExitConfiguration

func MergedExitConfig

func MergedExitConfig(conf *ExitConfiguration) (*ExitConfiguration, error)

type ExitServiceInfo

type ExitServiceInfo struct {
	Address string `json:"address"`
	Price   string `json:"price"`
}

type OnConnect

type OnConnect struct {
	C        chan struct{}
	Callback OnConnectFunc
	// contains filtered or unexported fields
}

OnConnect is a wrapper type for gomobile compatibility.

func NewOnConnect

func NewOnConnect(size int, cb OnConnectFunc) *OnConnect

NewOnConnect creates an OnConnect channel with a channel size and callback function.

func (*OnConnect) Next

func (c *OnConnect) Next()

Next waits and returns the next element from the channel.

type OnConnectFunc

type OnConnectFunc interface{ OnConnect() }

OnConnectFunc is a wrapper type for gomobile compatibility.

type Service

type Service struct {
	Name       string   `json:"name"`
	TCP        []uint32 `json:"tcp"`
	UDP        []uint32 `json:"udp"`
	Encryption string   `json:"encryption"`
}

type ServiceInfo

type ServiceInfo struct {
	MaxPrice  string            `json:"maxPrice"`
	ListenIP  string            `json:"listenIP"`
	IPFilter  *geo.IPFilter     `json:"ipFilter"`
	NknFilter *filter.NknFilter `json:"nknFilter"`
}

type TunaEntry

type TunaEntry struct {
	*Common
	// contains filtered or unexported fields
}

func NewTunaEntry

func NewTunaEntry(service Service, serviceInfo ServiceInfo, wallet *rvs.Wallet, client *rvs.MultiClient, config *EntryConfiguration) (*TunaEntry, error)

func (*TunaEntry) Close

func (te *TunaEntry) Close()

func (*TunaEntry) IsClosed

func (te *TunaEntry) IsClosed() bool

func (*TunaEntry) Start

func (te *TunaEntry) Start(shouldReconnect bool) error

func (*TunaEntry) StartReverse

func (te *TunaEntry) StartReverse(stream *smux.Stream) error

type TunaExit

type TunaExit struct {
	*Common
	OnConnect *OnConnect // override Common.OnConnect
	// contains filtered or unexported fields
}

func NewTunaExit

func NewTunaExit(services []Service, wallet *rvs.Wallet, client *rvs.MultiClient, config *ExitConfiguration) (*TunaExit, error)

func (*TunaExit) Close

func (te *TunaExit) Close()

func (*TunaExit) GetReverseIP

func (te *TunaExit) GetReverseIP() net.IP

func (*TunaExit) GetReverseTCPPorts

func (te *TunaExit) GetReverseTCPPorts() []uint32

func (*TunaExit) GetReverseUDPPorts

func (te *TunaExit) GetReverseUDPPorts() []uint32

func (*TunaExit) IsClosed

func (te *TunaExit) IsClosed() bool

func (*TunaExit) Start

func (te *TunaExit) Start() error

func (*TunaExit) StartReverse

func (te *TunaExit) StartReverse(shouldReconnect bool) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL