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  }