github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/yuubinsya/server.go (about) 1 package yuubinsya 2 3 import ( 4 "fmt" 5 "io" 6 "net" 7 "os" 8 9 "github.com/Asutorufa/yuhaiin/pkg/log" 10 "github.com/Asutorufa/yuhaiin/pkg/net/netapi" 11 "github.com/Asutorufa/yuhaiin/pkg/net/proxy/socks5/tools" 12 "github.com/Asutorufa/yuhaiin/pkg/net/proxy/yuubinsya/crypto" 13 "github.com/Asutorufa/yuhaiin/pkg/net/proxy/yuubinsya/plain" 14 "github.com/Asutorufa/yuhaiin/pkg/net/proxy/yuubinsya/types" 15 pl "github.com/Asutorufa/yuhaiin/pkg/protos/config/listener" 16 "github.com/Asutorufa/yuhaiin/pkg/protos/statistic" 17 ) 18 19 type server struct { 20 listener netapi.Listener 21 handshaker types.Handshaker 22 23 *netapi.ChannelServer 24 25 packetAuth types.Auth 26 } 27 28 func init() { 29 pl.RegisterProtocol(NewServer) 30 } 31 32 func NewServer(config *pl.Inbound_Yuubinsya) func(netapi.Listener) (netapi.Accepter, error) { 33 return func(ii netapi.Listener) (netapi.Accepter, error) { 34 auth, err := NewAuth(config.Yuubinsya.GetUdpEncrypt(), []byte(config.Yuubinsya.Password)) 35 if err != nil { 36 return nil, err 37 } 38 39 s := &server{ 40 listener: ii, 41 handshaker: NewHandshaker( 42 true, 43 config.Yuubinsya.GetTcpEncrypt(), 44 []byte(config.Yuubinsya.Password), 45 ), 46 47 ChannelServer: netapi.NewChannelServer(), 48 packetAuth: auth, 49 } 50 51 go log.IfErr("yuubinsya udp server", s.startUDP) 52 go log.IfErr("yuubinsya tcp server", s.startTCP) 53 54 return s, nil 55 } 56 } 57 58 func (y *server) startUDP() error { 59 packet, err := y.listener.Packet(y.Context()) 60 if err != nil { 61 return err 62 } 63 defer packet.Close() 64 65 StartUDPServer(packet, y.SendPacket, y.packetAuth, true) 66 67 return nil 68 } 69 70 func (y *server) startTCP() (err error) { 71 lis, err := y.listener.Stream(y.Context()) 72 if err != nil { 73 return err 74 } 75 defer lis.Close() 76 77 log.Info("new yuubinsya server", "host", lis.Addr()) 78 79 for { 80 conn, err := lis.Accept() 81 if err != nil { 82 return err 83 } 84 85 go log.IfErr("yuubinsya tcp handle", func() error { return y.handle(conn) }, io.EOF, os.ErrDeadlineExceeded) 86 } 87 } 88 89 func (y *server) handle(conn net.Conn) error { 90 c, err := y.handshaker.Handshake(conn) 91 if err != nil { 92 return fmt.Errorf("handshake failed: %w", err) 93 } 94 95 net, err := y.handshaker.DecodeHeader(c) 96 if err != nil { 97 return fmt.Errorf("parse header failed: %w", err) 98 } 99 100 switch net { 101 case types.TCP: 102 target, err := tools.ResolveAddr(c) 103 if err != nil { 104 return fmt.Errorf("resolve addr failed: %w", err) 105 } 106 107 addr := target.Address(statistic.Type_tcp) 108 109 return y.SendStream(&netapi.StreamMeta{ 110 Source: c.RemoteAddr(), 111 Destination: addr, 112 Inbound: c.LocalAddr(), 113 Src: c, 114 Address: addr, 115 }) 116 117 case types.UDP: 118 pc := newPacketConn(c, y.handshaker, true) 119 defer pc.Close() 120 121 log.Debug("new udp connect", "from", pc.RemoteAddr()) 122 123 for { 124 buf, addr, err := netapi.ReadFrom(pc) 125 if err != nil { 126 return err 127 } 128 err = y.SendPacket(&netapi.Packet{ 129 Src: pc.RemoteAddr(), 130 Dst: addr, 131 Payload: buf, 132 WriteBack: pc.WriteTo, 133 }) 134 135 if err != nil { 136 return err 137 } 138 } 139 } 140 141 return nil 142 } 143 144 func (y *server) Close() error { 145 if y.listener == nil { 146 return nil 147 } 148 return y.listener.Close() 149 } 150 151 func NewHandshaker(server bool, encrypted bool, password []byte) types.Handshaker { 152 hash := types.Salt(password) 153 154 if !encrypted { 155 return plain.Handshaker(hash) 156 } 157 158 return crypto.NewHandshaker(server, hash, password) 159 } 160 161 func NewAuth(crypt bool, password []byte) (types.Auth, error) { 162 password = types.Salt(password) 163 164 if !crypt { 165 return plain.NewAuth(password), nil 166 } 167 168 return crypto.GetAuth(password) 169 }