func init() { common.Must(internet.RegisterTransportDialer(internet.TransportProtocol_UDP, func(ctx context.Context, dest v2net.Destination) (internet.Connection, error) { src := internet.DialerSourceFromContext(ctx) conn, err := internet.DialSystem(src, dest) if err != nil { return nil, err } // TODO: handle dialer options return internal.NewConnection(internal.NewConnectionID(src, dest), conn, internal.NoOpConnectionRecyler{}, internal.ReuseConnection(false)), nil })) }
func DialKCP(ctx context.Context, dest v2net.Destination) (internet.Connection, error) { dest.Network = v2net.Network_UDP log.Info("KCP|Dialer: Dialing KCP to ", dest) src := internet.DialerSourceFromContext(ctx) id := internal.NewConnectionID(src, dest) conn := globalPool.Get(id) if conn == nil { rawConn, err := internet.DialSystem(src, dest) if err != nil { log.Error("KCP|Dialer: Failed to dial to dest: ", err) return nil, err } c := &ClientConnection{ Conn: rawConn, id: id, } go c.Run() conn = c } kcpSettings := internet.TransportSettingsFromContext(ctx).(*Config) clientConn := conn.(*ClientConnection) header, err := kcpSettings.GetPackerHeader() if err != nil { return nil, errors.Base(err).Message("KCP|Dialer: Failed to create packet header.") } security, err := kcpSettings.GetSecurity() if err != nil { return nil, errors.Base(err).Message("KCP|Dialer: Failed to create security.") } clientConn.ResetSecurity(header, security) conv := uint16(atomic.AddUint32(&globalConv, 1)) session := NewConnection(conv, clientConn, globalPool, kcpSettings) var iConn internet.Connection iConn = session if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil { switch securitySettings := securitySettings.(type) { case *v2tls.Config: config := securitySettings.GetTLSConfig() if dest.Address.Family().IsDomain() { config.ServerName = dest.Address.Domain() } tlsConn := tls.Client(iConn, config) iConn = UnreusableConnection{Conn: tlsConn} } } return iConn, nil }
func Dial(ctx context.Context, dest v2net.Destination) (internet.Connection, error) { log.Info("Internet|TCP: Dailing TCP to ", dest) src := internet.DialerSourceFromContext(ctx) tcpSettings := internet.TransportSettingsFromContext(ctx).(*Config) id := internal.NewConnectionID(src, dest) var conn net.Conn if dest.Network == v2net.Network_TCP && tcpSettings.IsConnectionReuse() { conn = globalCache.Get(id) } if conn == nil { var err error conn, err = internet.DialSystem(src, dest) if err != nil { return nil, err } if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil { tlsConfig, ok := securitySettings.(*v2tls.Config) if ok { config := tlsConfig.GetTLSConfig() if dest.Address.Family().IsDomain() { config.ServerName = dest.Address.Domain() } conn = tls.Client(conn, config) } } if tcpSettings.HeaderSettings != nil { headerConfig, err := tcpSettings.HeaderSettings.GetInstance() if err != nil { return nil, errors.Base(err).Message("Interent|TCP: Failed to get header settings.") } auth, err := internet.CreateConnectionAuthenticator(headerConfig) if err != nil { return nil, errors.Base(err).Message("Internet|TCP: Failed to create header authenticator.") } conn = auth.Client(conn) } } return internal.NewConnection(id, conn, globalCache, internal.ReuseConnection(tcpSettings.IsConnectionReuse())), nil }
func Dial(ctx context.Context, dest v2net.Destination) (internet.Connection, error) { log.Info("WebSocket|Dialer: Creating connection to ", dest) src := internet.DialerSourceFromContext(ctx) wsSettings := internet.TransportSettingsFromContext(ctx).(*Config) id := internal.NewConnectionID(src, dest) var conn *wsconn if dest.Network == v2net.Network_TCP && wsSettings.IsConnectionReuse() { connt := globalCache.Get(id) if connt != nil { conn = connt.(*wsconn) } } if conn == nil { var err error conn, err = wsDial(ctx, dest) if err != nil { log.Warning("WebSocket|Dialer: Dial failed: ", err) return nil, err } } return internal.NewConnection(id, conn, globalCache, internal.ReuseConnection(wsSettings.IsConnectionReuse())), nil }
func (v *Listener) OnReceive(payload *buf.Buffer, src v2net.Destination, originalDest v2net.Destination) { defer payload.Release() segments := v.reader.Read(payload.Bytes()) if len(segments) == 0 { log.Info("KCP|Listener: discarding invalid payload from ", src) return } if !v.running { return } v.Lock() defer v.Unlock() if !v.running { return } if payload.Len() < 4 { return } conv := segments[0].Conversation() cmd := segments[0].Command() id := ConnectionID{ Remote: src.Address, Port: src.Port, Conv: conv, } conn, found := v.sessions[id] if !found { if cmd == CommandTerminate { return } writer := &Writer{ id: id, hub: v.hub, dest: src, listener: v, } remoteAddr := &net.UDPAddr{ IP: src.Address.IP(), Port: int(src.Port), } localAddr := v.hub.Addr() sConn := &ServerConnection{ id: internal.NewConnectionID(v2net.LocalHostIP, src), local: localAddr, remote: remoteAddr, writer: &KCPPacketWriter{ Header: v.header, Writer: writer, Security: v.security, }, closer: writer, } conn = NewConnection(conv, sConn, v, v.config) select { case v.awaitingConns <- conn: case <-time.After(time.Second * 5): conn.Close() return } v.sessions[id] = conn } conn.Input(segments) }