package socket import ( "context" "fmt" "log" "net" "time" "tunnel/pkg/server/env" ) const defaultTimeout = 5 * time.Second type dialSocket struct { Proto string `opts:"default:tcp"` Addr string `opts:"required"` } func (s *dialSocket) String() string { return fmt.Sprintf("%s/%s", s.Proto, s.Addr) } func (s *dialSocket) New(e env.Env) (Conn, error) { return dial(context.TODO(), e, s.Proto, s.Addr) } func dial(ctx context.Context, e env.Env, proto, addr string) (*conn, error) { ctx, cancel := context.WithTimeout(ctx, defaultTimeout) defer cancel() var d net.Dialer proto, addr = parseProtoAddr(proto, e.Expand(addr)) conn, err := d.DialContext(ctx, proto, addr) if err != nil { return nil, err } la, ra := conn.LocalAddr(), conn.RemoteAddr() desc := fmt.Sprintf("%s/%s->%s", la.Network(), la, ra) info := fmt.Sprintf(">%s/%s", ra.Network(), ra) log.Println("dial", desc) return newConn(conn, desc, info), nil } func (s *dialSocket) Close() { } func init() { register("dial", "connect to the network address", dialSocket{}) }