Files

90 lines
2.0 KiB
Go

package tunnel
import (
"context"
"io"
"net"
"github.com/p4gefau1t/trojan-go/common"
)
// Conn is the TCP connection in the tunnel
type Conn interface {
net.Conn
Metadata() *Metadata
}
// PacketConn is the UDP packet stream in the tunnel
type PacketConn interface {
net.PacketConn
WriteWithMetadata([]byte, *Metadata) (int, error)
ReadWithMetadata([]byte) (int, *Metadata, error)
}
// ConnDialer creates TCP connections from the tunnel
type ConnDialer interface {
DialConn(*Address, Tunnel) (Conn, error)
}
// PacketDialer creates UDP packet stream from the tunnel
type PacketDialer interface {
DialPacket(Tunnel) (PacketConn, error)
}
// ConnListener accept TCP connections
type ConnListener interface {
AcceptConn(Tunnel) (Conn, error)
}
// PacketListener accept UDP packet stream
// We don't have any tunnel based on packet streams, so AcceptPacket will always receive a real PacketConn
type PacketListener interface {
AcceptPacket(Tunnel) (PacketConn, error)
}
// Dialer can dial to original server with a tunnel
type Dialer interface {
ConnDialer
PacketDialer
}
// Listener can accept TCP and UDP streams from a tunnel
type Listener interface {
ConnListener
PacketListener
}
// Client is the tunnel client based on stream connections
type Client interface {
Dialer
io.Closer
}
// Server is the tunnel server based on stream connections
type Server interface {
Listener
io.Closer
}
// Tunnel describes a tunnel, allowing creating a tunnel from another tunnel
// We assume that the lower tunnels know exatly how upper tunnels work, and lower tunnels is transparent for the upper tunnels
type Tunnel interface {
Name() string
NewClient(context.Context, Client) (Client, error)
NewServer(context.Context, Server) (Server, error)
}
var tunnels = make(map[string]Tunnel)
// RegisterTunnel register a tunnel by tunnel name
func RegisterTunnel(name string, tunnel Tunnel) {
tunnels[name] = tunnel
}
func GetTunnel(name string) (Tunnel, error) {
if t, ok := tunnels[name]; ok {
return t, nil
}
return nil, common.NewError("unknown tunnel name " + name)
}