github.com/ipfans/trojan-go@v0.11.0/tunnel/shadowsocks/server.go (about) 1 package shadowsocks 2 3 import ( 4 "context" 5 "net" 6 7 "github.com/shadowsocks/go-shadowsocks2/core" 8 9 "github.com/ipfans/trojan-go/common" 10 "github.com/ipfans/trojan-go/config" 11 "github.com/ipfans/trojan-go/log" 12 "github.com/ipfans/trojan-go/redirector" 13 "github.com/ipfans/trojan-go/tunnel" 14 ) 15 16 type Server struct { 17 core.Cipher 18 *redirector.Redirector 19 underlay tunnel.Server 20 redirAddr net.Addr 21 } 22 23 func (s *Server) AcceptConn(overlay tunnel.Tunnel) (tunnel.Conn, error) { 24 conn, err := s.underlay.AcceptConn(&Tunnel{}) 25 if err != nil { 26 return nil, common.NewError("shadowsocks failed to accept connection from underlying tunnel").Base(err) 27 } 28 rewindConn := common.NewRewindConn(conn) 29 rewindConn.SetBufferSize(1024) 30 defer rewindConn.StopBuffering() 31 32 // try to read something from this connection 33 buf := [1024]byte{} 34 testConn := s.Cipher.StreamConn(rewindConn) 35 if _, err := testConn.Read(buf[:]); err != nil { 36 // we are under attack 37 log.Error(common.NewError("shadowsocks failed to decrypt").Base(err)) 38 rewindConn.Rewind() 39 rewindConn.StopBuffering() 40 s.Redirect(&redirector.Redirection{ 41 RedirectTo: s.redirAddr, 42 InboundConn: rewindConn, 43 }) 44 return nil, common.NewError("invalid aead payload") 45 } 46 rewindConn.Rewind() 47 rewindConn.StopBuffering() 48 49 return &Conn{ 50 aeadConn: s.Cipher.StreamConn(rewindConn), 51 Conn: conn, 52 }, nil 53 } 54 55 func (s *Server) AcceptPacket(t tunnel.Tunnel) (tunnel.PacketConn, error) { 56 panic("not supported") 57 } 58 59 func (s *Server) Close() error { 60 return s.underlay.Close() 61 } 62 63 func NewServer(ctx context.Context, underlay tunnel.Server) (*Server, error) { 64 cfg := config.FromContext(ctx, Name).(*Config) 65 cipher, err := core.PickCipher(cfg.Shadowsocks.Method, nil, cfg.Shadowsocks.Password) 66 if err != nil { 67 return nil, common.NewError("invalid shadowsocks cipher").Base(err) 68 } 69 if cfg.RemoteHost == "" { 70 return nil, common.NewError("invalid shadowsocks redirection address") 71 } 72 if cfg.RemotePort == 0 { 73 return nil, common.NewError("invalid shadowsocks redirection port") 74 } 75 log.Debug("shadowsocks client created") 76 return &Server{ 77 underlay: underlay, 78 Cipher: cipher, 79 Redirector: redirector.NewRedirector(ctx), 80 redirAddr: tunnel.NewAddressFromHostPort("tcp", cfg.RemoteHost, cfg.RemotePort), 81 }, nil 82 }