server.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. package quic
  2. import (
  3. "bytes"
  4. "crypto/tls"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "net"
  9. "sync"
  10. "time"
  11. "github.com/lucas-clemente/quic-go/internal/handshake"
  12. "github.com/lucas-clemente/quic-go/internal/protocol"
  13. "github.com/lucas-clemente/quic-go/internal/utils"
  14. "github.com/lucas-clemente/quic-go/internal/wire"
  15. )
  16. // packetHandler handles packets
  17. type packetHandler interface {
  18. handlePacket(*receivedPacket)
  19. io.Closer
  20. destroy(error)
  21. GetPerspective() protocol.Perspective
  22. }
  23. type unknownPacketHandler interface {
  24. handlePacket(*receivedPacket)
  25. closeWithError(error) error
  26. }
  27. type packetHandlerManager interface {
  28. Add(protocol.ConnectionID, packetHandler)
  29. Retire(protocol.ConnectionID)
  30. Remove(protocol.ConnectionID)
  31. SetServer(unknownPacketHandler)
  32. CloseServer()
  33. }
  34. type quicSession interface {
  35. Session
  36. handlePacket(*receivedPacket)
  37. GetVersion() protocol.VersionNumber
  38. run() error
  39. destroy(error)
  40. closeForRecreating() protocol.PacketNumber
  41. closeRemote(error)
  42. }
  43. type sessionRunner interface {
  44. onHandshakeComplete(Session)
  45. retireConnectionID(protocol.ConnectionID)
  46. removeConnectionID(protocol.ConnectionID)
  47. }
  48. type runner struct {
  49. onHandshakeCompleteImpl func(Session)
  50. retireConnectionIDImpl func(protocol.ConnectionID)
  51. removeConnectionIDImpl func(protocol.ConnectionID)
  52. }
  53. func (r *runner) onHandshakeComplete(s Session) { r.onHandshakeCompleteImpl(s) }
  54. func (r *runner) retireConnectionID(c protocol.ConnectionID) { r.retireConnectionIDImpl(c) }
  55. func (r *runner) removeConnectionID(c protocol.ConnectionID) { r.removeConnectionIDImpl(c) }
  56. var _ sessionRunner = &runner{}
  57. // A Listener of QUIC
  58. type server struct {
  59. mutex sync.Mutex
  60. tlsConf *tls.Config
  61. config *Config
  62. conn net.PacketConn
  63. // If the server is started with ListenAddr, we create a packet conn.
  64. // If it is started with Listen, we take a packet conn as a parameter.
  65. createdPacketConn bool
  66. cookieGenerator *handshake.CookieGenerator
  67. sessionHandler packetHandlerManager
  68. // set as a member, so they can be set in the tests
  69. newSession func(connection, sessionRunner, protocol.ConnectionID /* original connection ID */, protocol.ConnectionID /* destination connection ID */, protocol.ConnectionID /* source connection ID */, *Config, *tls.Config, *handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error)
  70. serverError error
  71. errorChan chan struct{}
  72. closed bool
  73. sessionQueue chan Session
  74. sessionRunner sessionRunner
  75. logger utils.Logger
  76. }
  77. var _ Listener = &server{}
  78. var _ unknownPacketHandler = &server{}
  79. // ListenAddr creates a QUIC server listening on a given address.
  80. // The tls.Config must not be nil and must contain a certificate configuration.
  81. // The quic.Config may be nil, in that case the default values will be used.
  82. func ListenAddr(addr string, tlsConf *tls.Config, config *Config) (Listener, error) {
  83. udpAddr, err := net.ResolveUDPAddr("udp", addr)
  84. if err != nil {
  85. return nil, err
  86. }
  87. conn, err := net.ListenUDP("udp", udpAddr)
  88. if err != nil {
  89. return nil, err
  90. }
  91. serv, err := listen(conn, tlsConf, config)
  92. if err != nil {
  93. return nil, err
  94. }
  95. serv.createdPacketConn = true
  96. return serv, nil
  97. }
  98. // Listen listens for QUIC connections on a given net.PacketConn.
  99. // A single PacketConn only be used for a single call to Listen.
  100. // The PacketConn can be used for simultaneous calls to Dial.
  101. // QUIC connection IDs are used for demultiplexing the different connections.
  102. // The tls.Config must not be nil and must contain a certificate configuration.
  103. // The quic.Config may be nil, in that case the default values will be used.
  104. func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener, error) {
  105. return listen(conn, tlsConf, config)
  106. }
  107. func listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*server, error) {
  108. // TODO(#1655): only require that tls.Config.Certificates or tls.Config.GetCertificate is set
  109. if tlsConf == nil || len(tlsConf.Certificates) == 0 {
  110. return nil, errors.New("quic: Certificates not set in tls.Config")
  111. }
  112. config = populateServerConfig(config)
  113. for _, v := range config.Versions {
  114. if !protocol.IsValidVersion(v) {
  115. return nil, fmt.Errorf("%s is not a valid QUIC version", v)
  116. }
  117. }
  118. sessionHandler, err := getMultiplexer().AddConn(conn, config.ConnectionIDLength)
  119. if err != nil {
  120. return nil, err
  121. }
  122. s := &server{
  123. conn: conn,
  124. tlsConf: tlsConf,
  125. config: config,
  126. sessionHandler: sessionHandler,
  127. sessionQueue: make(chan Session, 5),
  128. errorChan: make(chan struct{}),
  129. newSession: newSession,
  130. logger: utils.DefaultLogger.WithPrefix("server"),
  131. }
  132. if err := s.setup(); err != nil {
  133. return nil, err
  134. }
  135. sessionHandler.SetServer(s)
  136. s.logger.Debugf("Listening for %s connections on %s", conn.LocalAddr().Network(), conn.LocalAddr().String())
  137. return s, nil
  138. }
  139. func (s *server) setup() error {
  140. s.sessionRunner = &runner{
  141. onHandshakeCompleteImpl: func(sess Session) { s.sessionQueue <- sess },
  142. retireConnectionIDImpl: s.sessionHandler.Retire,
  143. removeConnectionIDImpl: s.sessionHandler.Remove,
  144. }
  145. cookieGenerator, err := handshake.NewCookieGenerator()
  146. if err != nil {
  147. return err
  148. }
  149. s.cookieGenerator = cookieGenerator
  150. return nil
  151. }
  152. var defaultAcceptCookie = func(clientAddr net.Addr, cookie *Cookie) bool {
  153. if cookie == nil {
  154. return false
  155. }
  156. if time.Now().After(cookie.SentTime.Add(protocol.CookieExpiryTime)) {
  157. return false
  158. }
  159. var sourceAddr string
  160. if udpAddr, ok := clientAddr.(*net.UDPAddr); ok {
  161. sourceAddr = udpAddr.IP.String()
  162. } else {
  163. sourceAddr = clientAddr.String()
  164. }
  165. return sourceAddr == cookie.RemoteAddr
  166. }
  167. // populateServerConfig populates fields in the quic.Config with their default values, if none are set
  168. // it may be called with nil
  169. func populateServerConfig(config *Config) *Config {
  170. if config == nil {
  171. config = &Config{}
  172. }
  173. versions := config.Versions
  174. if len(versions) == 0 {
  175. versions = protocol.SupportedVersions
  176. }
  177. vsa := defaultAcceptCookie
  178. if config.AcceptCookie != nil {
  179. vsa = config.AcceptCookie
  180. }
  181. handshakeTimeout := protocol.DefaultHandshakeTimeout
  182. if config.HandshakeTimeout != 0 {
  183. handshakeTimeout = config.HandshakeTimeout
  184. }
  185. idleTimeout := protocol.DefaultIdleTimeout
  186. if config.IdleTimeout != 0 {
  187. idleTimeout = config.IdleTimeout
  188. }
  189. maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow
  190. if maxReceiveStreamFlowControlWindow == 0 {
  191. maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow
  192. }
  193. maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow
  194. if maxReceiveConnectionFlowControlWindow == 0 {
  195. maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow
  196. }
  197. maxIncomingStreams := config.MaxIncomingStreams
  198. if maxIncomingStreams == 0 {
  199. maxIncomingStreams = protocol.DefaultMaxIncomingStreams
  200. } else if maxIncomingStreams < 0 {
  201. maxIncomingStreams = 0
  202. }
  203. maxIncomingUniStreams := config.MaxIncomingUniStreams
  204. if maxIncomingUniStreams == 0 {
  205. maxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams
  206. } else if maxIncomingUniStreams < 0 {
  207. maxIncomingUniStreams = 0
  208. }
  209. connIDLen := config.ConnectionIDLength
  210. if connIDLen == 0 {
  211. connIDLen = protocol.DefaultConnectionIDLength
  212. }
  213. return &Config{
  214. Versions: versions,
  215. HandshakeTimeout: handshakeTimeout,
  216. IdleTimeout: idleTimeout,
  217. AcceptCookie: vsa,
  218. KeepAlive: config.KeepAlive,
  219. MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow,
  220. MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
  221. MaxIncomingStreams: maxIncomingStreams,
  222. MaxIncomingUniStreams: maxIncomingUniStreams,
  223. ConnectionIDLength: connIDLen,
  224. }
  225. }
  226. // Accept returns newly openend sessions
  227. func (s *server) Accept() (Session, error) {
  228. var sess Session
  229. select {
  230. case sess = <-s.sessionQueue:
  231. return sess, nil
  232. case <-s.errorChan:
  233. return nil, s.serverError
  234. }
  235. }
  236. // Close the server
  237. func (s *server) Close() error {
  238. s.mutex.Lock()
  239. defer s.mutex.Unlock()
  240. if s.closed {
  241. return nil
  242. }
  243. return s.closeWithMutex()
  244. }
  245. func (s *server) closeWithMutex() error {
  246. s.sessionHandler.CloseServer()
  247. if s.serverError == nil {
  248. s.serverError = errors.New("server closed")
  249. }
  250. var err error
  251. // If the server was started with ListenAddr, we created the packet conn.
  252. // We need to close it in order to make the go routine reading from that conn return.
  253. if s.createdPacketConn {
  254. err = s.conn.Close()
  255. }
  256. s.closed = true
  257. close(s.errorChan)
  258. return err
  259. }
  260. func (s *server) closeWithError(e error) error {
  261. s.mutex.Lock()
  262. defer s.mutex.Unlock()
  263. if s.closed {
  264. return nil
  265. }
  266. s.serverError = e
  267. return s.closeWithMutex()
  268. }
  269. // Addr returns the server's network address
  270. func (s *server) Addr() net.Addr {
  271. return s.conn.LocalAddr()
  272. }
  273. func (s *server) handlePacket(p *receivedPacket) {
  274. hdr := p.hdr
  275. // send a Version Negotiation Packet if the client is speaking a different protocol version
  276. if !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) {
  277. go s.sendVersionNegotiationPacket(p)
  278. return
  279. }
  280. if hdr.Type == protocol.PacketTypeInitial {
  281. go s.handleInitial(p)
  282. return
  283. }
  284. // TODO(#943): send Stateless Reset
  285. p.buffer.Release()
  286. }
  287. func (s *server) handleInitial(p *receivedPacket) {
  288. s.logger.Debugf("<- Received Initial packet.")
  289. sess, connID, err := s.handleInitialImpl(p)
  290. if err != nil {
  291. p.buffer.Release()
  292. s.logger.Errorf("Error occurred handling initial packet: %s", err)
  293. return
  294. }
  295. if sess == nil { // a retry was done
  296. p.buffer.Release()
  297. return
  298. }
  299. // Don't put the packet buffer back if a new session was created.
  300. // The session will handle the packet and take of that.
  301. serverSession := newServerSession(sess, s.config, s.logger)
  302. s.sessionHandler.Add(connID, serverSession)
  303. }
  304. func (s *server) handleInitialImpl(p *receivedPacket) (quicSession, protocol.ConnectionID, error) {
  305. hdr := p.hdr
  306. if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial {
  307. return nil, nil, errors.New("dropping Initial packet with too short connection ID")
  308. }
  309. if len(p.data) < protocol.MinInitialPacketSize {
  310. return nil, nil, errors.New("dropping too small Initial packet")
  311. }
  312. var cookie *Cookie
  313. var origDestConnectionID protocol.ConnectionID
  314. if len(hdr.Token) > 0 {
  315. c, err := s.cookieGenerator.DecodeToken(hdr.Token)
  316. if err == nil {
  317. cookie = &Cookie{
  318. RemoteAddr: c.RemoteAddr,
  319. SentTime: c.SentTime,
  320. }
  321. origDestConnectionID = c.OriginalDestConnectionID
  322. }
  323. }
  324. if !s.config.AcceptCookie(p.remoteAddr, cookie) {
  325. // Log the Initial packet now.
  326. // If no Retry is sent, the packet will be logged by the session.
  327. (&wire.ExtendedHeader{Header: *p.hdr}).Log(s.logger)
  328. return nil, nil, s.sendRetry(p.remoteAddr, hdr)
  329. }
  330. connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
  331. if err != nil {
  332. return nil, nil, err
  333. }
  334. s.logger.Debugf("Changing connection ID to %s.", connID)
  335. sess, err := s.createNewSession(
  336. p.remoteAddr,
  337. origDestConnectionID,
  338. hdr.DestConnectionID,
  339. hdr.SrcConnectionID,
  340. connID,
  341. hdr.Version,
  342. )
  343. if err != nil {
  344. return nil, nil, err
  345. }
  346. sess.handlePacket(p)
  347. return sess, connID, nil
  348. }
  349. func (s *server) createNewSession(
  350. remoteAddr net.Addr,
  351. origDestConnID protocol.ConnectionID,
  352. clientDestConnID protocol.ConnectionID,
  353. destConnID protocol.ConnectionID,
  354. srcConnID protocol.ConnectionID,
  355. version protocol.VersionNumber,
  356. ) (quicSession, error) {
  357. params := &handshake.TransportParameters{
  358. InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData,
  359. InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData,
  360. InitialMaxStreamDataUni: protocol.InitialMaxStreamData,
  361. InitialMaxData: protocol.InitialMaxData,
  362. IdleTimeout: s.config.IdleTimeout,
  363. MaxBidiStreams: uint64(s.config.MaxIncomingStreams),
  364. MaxUniStreams: uint64(s.config.MaxIncomingUniStreams),
  365. DisableMigration: true,
  366. // TODO(#855): generate a real token
  367. StatelessResetToken: bytes.Repeat([]byte{42}, 16),
  368. OriginalConnectionID: origDestConnID,
  369. }
  370. sess, err := s.newSession(
  371. &conn{pconn: s.conn, currentAddr: remoteAddr},
  372. s.sessionRunner,
  373. clientDestConnID,
  374. destConnID,
  375. srcConnID,
  376. s.config,
  377. s.tlsConf,
  378. params,
  379. s.logger,
  380. version,
  381. )
  382. if err != nil {
  383. return nil, err
  384. }
  385. go sess.run()
  386. return sess, nil
  387. }
  388. func (s *server) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
  389. token, err := s.cookieGenerator.NewToken(remoteAddr, hdr.DestConnectionID)
  390. if err != nil {
  391. return err
  392. }
  393. connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
  394. if err != nil {
  395. return err
  396. }
  397. replyHdr := &wire.ExtendedHeader{}
  398. replyHdr.IsLongHeader = true
  399. replyHdr.Type = protocol.PacketTypeRetry
  400. replyHdr.Version = hdr.Version
  401. replyHdr.SrcConnectionID = connID
  402. replyHdr.DestConnectionID = hdr.SrcConnectionID
  403. replyHdr.OrigDestConnectionID = hdr.DestConnectionID
  404. replyHdr.Token = token
  405. s.logger.Debugf("Changing connection ID to %s.\n-> Sending Retry", connID)
  406. replyHdr.Log(s.logger)
  407. buf := &bytes.Buffer{}
  408. if err := replyHdr.Write(buf, hdr.Version); err != nil {
  409. return err
  410. }
  411. if _, err := s.conn.WriteTo(buf.Bytes(), remoteAddr); err != nil {
  412. s.logger.Debugf("Error sending Retry: %s", err)
  413. }
  414. return nil
  415. }
  416. func (s *server) sendVersionNegotiationPacket(p *receivedPacket) {
  417. defer p.buffer.Release()
  418. hdr := p.hdr
  419. s.logger.Debugf("Client offered version %s, sending Version Negotiation", hdr.Version)
  420. data, err := wire.ComposeVersionNegotiation(hdr.SrcConnectionID, hdr.DestConnectionID, s.config.Versions)
  421. if err != nil {
  422. s.logger.Debugf("Error composing Version Negotiation: %s", err)
  423. return
  424. }
  425. if _, err := s.conn.WriteTo(data, p.remoteAddr); err != nil {
  426. s.logger.Debugf("Error sending Version Negotiation: %s", err)
  427. }
  428. }