github.com/Psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/quic/gquic-go/server_tls.go (about) 1 package gquic 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "errors" 7 "net" 8 9 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/internal/handshake" 10 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/internal/protocol" 11 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/internal/utils" 12 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/quic/gquic-go/internal/wire" 13 "github.com/bifurcation/mint" 14 ) 15 16 type tlsSession struct { 17 connID protocol.ConnectionID 18 sess quicSession 19 } 20 21 type serverTLS struct { 22 conn net.PacketConn 23 config *Config 24 mintConf *mint.Config 25 params *handshake.TransportParameters 26 cookieGenerator *handshake.CookieGenerator 27 28 newSession func(connection, sessionRunner, protocol.ConnectionID, protocol.ConnectionID, protocol.ConnectionID, protocol.PacketNumber, *Config, *mint.Config, <-chan handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error) 29 30 sessionRunner sessionRunner 31 sessionChan chan<- tlsSession 32 33 logger utils.Logger 34 } 35 36 func newServerTLS( 37 conn net.PacketConn, 38 config *Config, 39 runner sessionRunner, 40 tlsConf *tls.Config, 41 logger utils.Logger, 42 ) (*serverTLS, <-chan tlsSession, error) { 43 cookieGenerator, err := handshake.NewCookieGenerator() 44 if err != nil { 45 return nil, nil, err 46 } 47 params := &handshake.TransportParameters{ 48 StreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow, 49 ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow, 50 IdleTimeout: config.IdleTimeout, 51 MaxBidiStreams: uint16(config.MaxIncomingStreams), 52 MaxUniStreams: uint16(config.MaxIncomingUniStreams), 53 DisableMigration: true, 54 // TODO(#855): generate a real token 55 StatelessResetToken: bytes.Repeat([]byte{42}, 16), 56 } 57 mconf, err := tlsToMintConfig(tlsConf, protocol.PerspectiveServer) 58 if err != nil { 59 return nil, nil, err 60 } 61 62 sessionChan := make(chan tlsSession) 63 s := &serverTLS{ 64 conn: conn, 65 config: config, 66 mintConf: mconf, 67 sessionRunner: runner, 68 sessionChan: sessionChan, 69 cookieGenerator: cookieGenerator, 70 params: params, 71 newSession: newTLSServerSession, 72 logger: logger, 73 } 74 return s, sessionChan, nil 75 } 76 77 func (s *serverTLS) HandleInitial(p *receivedPacket) { 78 // TODO: add a check that DestConnID == SrcConnID 79 s.logger.Debugf("<- Received Initial packet.") 80 sess, connID, err := s.handleInitialImpl(p) 81 if err != nil { 82 s.logger.Errorf("Error occurred handling initial packet: %s", err) 83 return 84 } 85 if sess == nil { // a stateless reset was done 86 return 87 } 88 s.sessionChan <- tlsSession{ 89 connID: connID, 90 sess: sess, 91 } 92 } 93 94 func (s *serverTLS) handleInitialImpl(p *receivedPacket) (quicSession, protocol.ConnectionID, error) { 95 hdr := p.header 96 if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { 97 return nil, nil, errors.New("dropping Initial packet with too short connection ID") 98 } 99 if len(hdr.Raw)+len(p.data) < protocol.MinInitialPacketSize { 100 return nil, nil, errors.New("dropping too small Initial packet") 101 } 102 103 var cookie *handshake.Cookie 104 if len(hdr.Token) > 0 { 105 c, err := s.cookieGenerator.DecodeToken(hdr.Token) 106 if err == nil { 107 cookie = c 108 } 109 } 110 if !s.config.AcceptCookie(p.remoteAddr, cookie) { 111 // Log the Initial packet now. 112 // If no Retry is sent, the packet will be logged by the session. 113 p.header.Log(s.logger) 114 return nil, nil, s.sendRetry(p.remoteAddr, hdr) 115 } 116 117 extHandler := handshake.NewExtensionHandlerServer(s.params, s.config.Versions, hdr.Version, s.logger) 118 mconf := s.mintConf.Clone() 119 mconf.ExtensionHandler = extHandler 120 121 connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) 122 if err != nil { 123 return nil, nil, err 124 } 125 s.logger.Debugf("Changing connection ID to %s.", connID) 126 sess, err := s.newSession( 127 &conn{pconn: s.conn, currentAddr: p.remoteAddr}, 128 s.sessionRunner, 129 hdr.DestConnectionID, 130 hdr.SrcConnectionID, 131 connID, 132 1, 133 s.config, 134 mconf, 135 extHandler.GetPeerParams(), 136 s.logger, 137 hdr.Version, 138 ) 139 if err != nil { 140 return nil, nil, err 141 } 142 go sess.run() 143 sess.handlePacket(p) 144 return sess, connID, nil 145 } 146 147 func (s *serverTLS) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error { 148 token, err := s.cookieGenerator.NewToken(remoteAddr) 149 if err != nil { 150 return err 151 } 152 connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) 153 if err != nil { 154 return err 155 } 156 replyHdr := &wire.Header{ 157 IsLongHeader: true, 158 Type: protocol.PacketTypeRetry, 159 Version: hdr.Version, 160 SrcConnectionID: connID, 161 DestConnectionID: hdr.SrcConnectionID, 162 OrigDestConnectionID: hdr.DestConnectionID, 163 Token: token, 164 } 165 s.logger.Debugf("Changing connection ID to %s.\n-> Sending Retry", connID) 166 replyHdr.Log(s.logger) 167 buf := &bytes.Buffer{} 168 if err := replyHdr.Write(buf, protocol.PerspectiveServer, hdr.Version); err != nil { 169 return err 170 } 171 if _, err := s.conn.WriteTo(buf.Bytes(), remoteAddr); err != nil { 172 s.logger.Debugf("Error sending Retry: %s", err) 173 } 174 return nil 175 }