1 /*
2  * ngtcp2
3  *
4  * Copyright (c) 2017 ngtcp2 contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #include <chrono>
26 #include <cstdlib>
27 #include <cassert>
28 #include <cstring>
29 #include <iostream>
30 #include <algorithm>
31 #include <memory>
32 #include <fstream>
33 #include <iomanip>
34 
35 #include <unistd.h>
36 #include <getopt.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <netdb.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <sys/mman.h>
43 #include <netinet/udp.h>
44 #include <net/if.h>
45 
46 #include <http-parser/http_parser.h>
47 
48 #include "h09server.h"
49 #include "network.h"
50 #include "debug.h"
51 #include "util.h"
52 #include "shared.h"
53 #include "http.h"
54 #include "template.h"
55 
56 using namespace ngtcp2;
57 using namespace std::literals;
58 
59 #ifndef NGTCP2_ENABLE_UDP_GSO
60 #  ifdef UDP_SEGMENT
61 #    define NGTCP2_ENABLE_UDP_GSO 1
62 #  else // !UDP_SEGMENT
63 #    define NGTCP2_ENABLE_UDP_GSO 0
64 #  endif // !UDP_SEGMENT
65 #endif   // NGTCP2_ENABLE_UDP_GSO
66 
67 namespace {
68 constexpr size_t NGTCP2_SV_SCIDLEN = 18;
69 } // namespace
70 
71 namespace {
72 auto randgen = util::make_mt19937();
73 } // namespace
74 
75 Config config{};
76 
Stream(int64_t stream_id,Handler * handler)77 Stream::Stream(int64_t stream_id, Handler *handler)
78     : stream_id(stream_id), handler(handler), eos(false) {
79   nghttp3_buf_init(&respbuf);
80   htp.data = this;
81   http_parser_init(&htp, HTTP_REQUEST);
82 }
83 
84 namespace {
85 constexpr char NGTCP2_SERVER[] = "ngtcp2 server";
86 } // namespace
87 
88 namespace {
make_status_body(unsigned int status_code)89 std::string make_status_body(unsigned int status_code) {
90   auto status_string = std::to_string(status_code);
91   auto reason_phrase = http::get_reason_phrase(status_code);
92 
93   std::string body;
94   body = "<html><head><title>";
95   body += status_string;
96   body += ' ';
97   body += reason_phrase;
98   body += "</title></head><body><h1>";
99   body += status_string;
100   body += ' ';
101   body += reason_phrase;
102   body += "</h1><hr><address>";
103   body += NGTCP2_SERVER;
104   body += " at port ";
105   body += std::to_string(config.port);
106   body += "</address>";
107   body += "</body></html>";
108   return body;
109 }
110 } // namespace
111 
112 struct Request {
113   std::string path;
114   struct {
115     int32_t urgency;
116     int inc;
117   } pri;
118 };
119 
120 namespace {
request_path(const std::string_view & uri)121 Request request_path(const std::string_view &uri) {
122   http_parser_url u;
123   Request req;
124 
125   req.pri.urgency = -1;
126   req.pri.inc = -1;
127 
128   http_parser_url_init(&u);
129 
130   if (auto rv = http_parser_parse_url(uri.data(), uri.size(),
131                                       /* is_connect = */ 0, &u);
132       rv != 0) {
133     return req;
134   }
135 
136   if (u.field_set & (1 << UF_PATH)) {
137     req.path = std::string(uri.data() + u.field_data[UF_PATH].off,
138                            u.field_data[UF_PATH].len);
139     if (req.path.find('%') != std::string::npos) {
140       req.path = util::percent_decode(std::begin(req.path), std::end(req.path));
141     }
142     if (!req.path.empty() && req.path.back() == '/') {
143       req.path += "index.html";
144     }
145   } else {
146     req.path = "/index.html";
147   }
148 
149   req.path = util::normalize_path(req.path);
150   if (req.path == "/") {
151     req.path = "/index.html";
152   }
153 
154   if (u.field_set & (1 << UF_QUERY)) {
155     static constexpr char urgency_prefix[] = "u=";
156     static constexpr char inc_prefix[] = "i=";
157     auto q = std::string(uri.data() + u.field_data[UF_QUERY].off,
158                          u.field_data[UF_QUERY].len);
159     for (auto p = std::begin(q); p != std::end(q);) {
160       if (util::istarts_with(p, std::end(q), std::begin(urgency_prefix),
161                              std::end(urgency_prefix) - 1)) {
162         auto urgency_start = p + sizeof(urgency_prefix) - 1;
163         auto urgency_end = std::find(urgency_start, std::end(q), '&');
164         if (urgency_start + 1 == urgency_end && '0' <= *urgency_start &&
165             *urgency_start <= '7') {
166           req.pri.urgency = *urgency_start - '0';
167         }
168         if (urgency_end == std::end(q)) {
169           break;
170         }
171         p = urgency_end + 1;
172         continue;
173       }
174       if (util::istarts_with(p, std::end(q), std::begin(inc_prefix),
175                              std::end(inc_prefix) - 1)) {
176         auto inc_start = p + sizeof(inc_prefix) - 1;
177         auto inc_end = std::find(inc_start, std::end(q), '&');
178         if (inc_start + 1 == inc_end &&
179             (*inc_start == '0' || *inc_start == '1')) {
180           req.pri.inc = *inc_start - '0';
181         }
182         if (inc_end == std::end(q)) {
183           break;
184         }
185         p = inc_end + 1;
186         continue;
187       }
188 
189       p = std::find(p, std::end(q), '&');
190       if (p == std::end(q)) {
191         break;
192       }
193       ++p;
194     }
195   }
196   return req;
197 }
198 } // namespace
199 
200 enum FileEntryFlag {
201   FILE_ENTRY_TYPE_DIR = 0x1,
202 };
203 
204 struct FileEntry {
205   uint64_t len;
206   void *map;
207   int fd;
208   uint8_t flags;
209 };
210 
211 namespace {
212 std::unordered_map<std::string, FileEntry> file_cache;
213 } // namespace
214 
open_file(const std::string & path)215 std::pair<FileEntry, int> Stream::open_file(const std::string &path) {
216   auto it = file_cache.find(path);
217   if (it != std::end(file_cache)) {
218     return {(*it).second, 0};
219   }
220 
221   auto fd = open(path.c_str(), O_RDONLY);
222   if (fd == -1) {
223     return {{}, -1};
224   }
225 
226   struct stat st {};
227   if (fstat(fd, &st) != 0) {
228     close(fd);
229     return {{}, -1};
230   }
231 
232   FileEntry fe{};
233   if (st.st_mode & S_IFDIR) {
234     fe.flags |= FILE_ENTRY_TYPE_DIR;
235     fe.fd = -1;
236     close(fd);
237   } else {
238     fe.fd = fd;
239     fe.len = st.st_size;
240     fe.map = mmap(nullptr, fe.len, PROT_READ, MAP_SHARED, fd, 0);
241     if (fe.map == MAP_FAILED) {
242       std::cerr << "mmap: " << strerror(errno) << std::endl;
243       close(fd);
244       return {{}, -1};
245     }
246   }
247 
248   file_cache.emplace(path, fe);
249 
250   return {std::move(fe), 0};
251 }
252 
map_file(const FileEntry & fe)253 void Stream::map_file(const FileEntry &fe) {
254   respbuf.begin = respbuf.pos = static_cast<uint8_t *>(fe.map);
255   respbuf.end = respbuf.last = respbuf.begin + fe.len;
256 }
257 
send_status_response(unsigned int status_code)258 int Stream::send_status_response(unsigned int status_code) {
259   status_resp_body = make_status_body(status_code);
260 
261   respbuf.begin = respbuf.pos =
262       reinterpret_cast<uint8_t *>(status_resp_body.data());
263   respbuf.end = respbuf.last = respbuf.begin + status_resp_body.size();
264 
265   handler->add_sendq(this);
266   handler->shutdown_read(stream_id, 0);
267 
268   return 0;
269 }
270 
start_response()271 int Stream::start_response() {
272   if (uri.empty()) {
273     return send_status_response(400);
274   }
275 
276   auto req = request_path(uri);
277   if (req.path.empty()) {
278     return send_status_response(400);
279   }
280 
281   auto path = config.htdocs + req.path;
282   auto [fe, rv] = open_file(path);
283   if (rv != 0) {
284     send_status_response(404);
285     return 0;
286   }
287 
288   if (fe.flags & FILE_ENTRY_TYPE_DIR) {
289     send_status_response(308);
290     return 0;
291   }
292 
293   map_file(fe);
294 
295   if (!config.quiet) {
296     std::array<nghttp3_nv, 1> nva{
297         util::make_nv(":status", "200"),
298     };
299 
300     debug::print_http_response_headers(stream_id, nva.data(), nva.size());
301   }
302 
303   handler->add_sendq(this);
304 
305   return 0;
306 }
307 
308 namespace {
writecb(struct ev_loop * loop,ev_io * w,int revents)309 void writecb(struct ev_loop *loop, ev_io *w, int revents) {
310   ev_io_stop(loop, w);
311 
312   auto h = static_cast<Handler *>(w->data);
313   auto s = h->server();
314 
315   switch (h->on_write()) {
316   case 0:
317   case NETWORK_ERR_CLOSE_WAIT:
318     return;
319   default:
320     s->remove(h);
321   }
322 }
323 } // namespace
324 
325 namespace {
timeoutcb(struct ev_loop * loop,ev_timer * w,int revents)326 void timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
327   auto h = static_cast<Handler *>(w->data);
328   auto s = h->server();
329 
330   if (ngtcp2_conn_is_in_closing_period(h->conn())) {
331     if (!config.quiet) {
332       std::cerr << "Closing Period is over" << std::endl;
333     }
334 
335     s->remove(h);
336     return;
337   }
338   if (h->draining()) {
339     if (!config.quiet) {
340       std::cerr << "Draining Period is over" << std::endl;
341     }
342 
343     s->remove(h);
344     return;
345   }
346 
347   if (!config.quiet) {
348     std::cerr << "Timeout" << std::endl;
349   }
350 
351   h->start_draining_period();
352 }
353 } // namespace
354 
355 namespace {
retransmitcb(struct ev_loop * loop,ev_timer * w,int revents)356 void retransmitcb(struct ev_loop *loop, ev_timer *w, int revents) {
357   int rv;
358 
359   auto h = static_cast<Handler *>(w->data);
360   auto s = h->server();
361 
362   if (!config.quiet) {
363     std::cerr << "Timer expired" << std::endl;
364   }
365 
366   rv = h->handle_expiry();
367   if (rv != 0) {
368     goto fail;
369   }
370 
371   rv = h->on_write();
372   if (rv != 0) {
373     goto fail;
374   }
375 
376   return;
377 
378 fail:
379   switch (rv) {
380   case NETWORK_ERR_CLOSE_WAIT:
381     ev_timer_stop(loop, w);
382     return;
383   default:
384     s->remove(h);
385     return;
386   }
387 }
388 } // namespace
389 
Handler(struct ev_loop * loop,Server * server)390 Handler::Handler(struct ev_loop *loop, Server *server)
391     : loop_(loop),
392       server_(server),
393       qlog_(nullptr),
394       scid_{},
395       nkey_update_(0),
396       draining_(false) {
397   ev_io_init(&wev_, writecb, 0, EV_WRITE);
398   wev_.data = this;
399   ev_timer_init(&timer_, timeoutcb, 0.,
400                 static_cast<double>(config.timeout) / NGTCP2_SECONDS);
401   timer_.data = this;
402   ev_timer_init(&rttimer_, retransmitcb, 0., 0.);
403   rttimer_.data = this;
404 }
405 
~Handler()406 Handler::~Handler() {
407   if (!config.quiet) {
408     std::cerr << scid_ << " Closing QUIC connection " << std::endl;
409   }
410 
411   ev_timer_stop(loop_, &rttimer_);
412   ev_timer_stop(loop_, &timer_);
413   ev_io_stop(loop_, &wev_);
414 
415   if (qlog_) {
416     fclose(qlog_);
417   }
418 }
419 
420 namespace {
handshake_completed(ngtcp2_conn * conn,void * user_data)421 int handshake_completed(ngtcp2_conn *conn, void *user_data) {
422   auto h = static_cast<Handler *>(user_data);
423 
424   if (!config.quiet) {
425     debug::handshake_completed(conn, user_data);
426   }
427 
428   if (h->handshake_completed() != 0) {
429     return NGTCP2_ERR_CALLBACK_FAILURE;
430   }
431 
432   return 0;
433 }
434 } // namespace
435 
handshake_completed()436 int Handler::handshake_completed() {
437   if (!config.quiet) {
438     std::cerr << "Negotiated cipher suite is " << tls_session_.get_cipher_name()
439               << std::endl;
440     std::cerr << "Negotiated ALPN is " << tls_session_.get_selected_alpn()
441               << std::endl;
442   }
443 
444   std::array<uint8_t, NGTCP2_CRYPTO_MAX_REGULAR_TOKENLEN> token;
445 
446   auto path = ngtcp2_conn_get_path(conn_);
447   auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
448                std::chrono::system_clock::now().time_since_epoch())
449                .count();
450 
451   auto tokenlen = ngtcp2_crypto_generate_regular_token(
452       token.data(), config.static_secret.data(), config.static_secret.size(),
453       path->remote.addr, path->remote.addrlen, t);
454   if (tokenlen < 0) {
455     if (!config.quiet) {
456       std::cerr << "Unable to generate token" << std::endl;
457     }
458     return 0;
459   }
460 
461   if (auto rv = ngtcp2_conn_submit_new_token(conn_, token.data(), tokenlen);
462       rv != 0) {
463     if (!config.quiet) {
464       std::cerr << "ngtcp2_conn_submit_new_token: " << ngtcp2_strerror(rv)
465                 << std::endl;
466     }
467     return -1;
468   }
469 
470   return 0;
471 }
472 
473 namespace {
do_hp_mask(uint8_t * dest,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx,const uint8_t * sample)474 int do_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
475                const ngtcp2_crypto_cipher_ctx *hp_ctx, const uint8_t *sample) {
476   if (ngtcp2_crypto_hp_mask(dest, hp, hp_ctx, sample) != 0) {
477     return NGTCP2_ERR_CALLBACK_FAILURE;
478   }
479 
480   if (!config.quiet && config.show_secret) {
481     debug::print_hp_mask(dest, NGTCP2_HP_MASKLEN, sample, NGTCP2_HP_SAMPLELEN);
482   }
483 
484   return 0;
485 }
486 } // namespace
487 
488 namespace {
recv_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,uint64_t offset,const uint8_t * data,size_t datalen,void * user_data)489 int recv_crypto_data(ngtcp2_conn *conn, ngtcp2_crypto_level crypto_level,
490                      uint64_t offset, const uint8_t *data, size_t datalen,
491                      void *user_data) {
492   if (!config.quiet && !config.no_quic_dump) {
493     debug::print_crypto_data(crypto_level, data, datalen);
494   }
495 
496   return ngtcp2_crypto_recv_crypto_data_cb(conn, crypto_level, offset, data,
497                                            datalen, user_data);
498 }
499 } // namespace
500 
501 namespace {
recv_stream_data(ngtcp2_conn * conn,uint32_t flags,int64_t stream_id,uint64_t offset,const uint8_t * data,size_t datalen,void * user_data,void * stream_user_data)502 int recv_stream_data(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
503                      uint64_t offset, const uint8_t *data, size_t datalen,
504                      void *user_data, void *stream_user_data) {
505   auto h = static_cast<Handler *>(user_data);
506 
507   if (h->recv_stream_data(flags, stream_id, data, datalen) != 0) {
508     return NGTCP2_ERR_CALLBACK_FAILURE;
509   }
510 
511   return 0;
512 }
513 } // namespace
514 
515 namespace {
acked_stream_data_offset(ngtcp2_conn * conn,int64_t stream_id,uint64_t offset,uint64_t datalen,void * user_data,void * stream_user_data)516 int acked_stream_data_offset(ngtcp2_conn *conn, int64_t stream_id,
517                              uint64_t offset, uint64_t datalen, void *user_data,
518                              void *stream_user_data) {
519   auto h = static_cast<Handler *>(user_data);
520   if (h->acked_stream_data_offset(stream_id, offset, datalen) != 0) {
521     return NGTCP2_ERR_CALLBACK_FAILURE;
522   }
523   return 0;
524 }
525 } // namespace
526 
acked_stream_data_offset(int64_t stream_id,uint64_t offset,uint64_t datalen)527 int Handler::acked_stream_data_offset(int64_t stream_id, uint64_t offset,
528                                       uint64_t datalen) {
529   auto it = streams_.find(stream_id);
530   assert(it != std::end(streams_));
531   auto &stream = (*it).second;
532   (void)stream;
533 
534   assert(static_cast<uint64_t>(stream->respbuf.end - stream->respbuf.begin) >=
535          offset + datalen);
536 
537   return 0;
538 }
539 
540 namespace {
stream_open(ngtcp2_conn * conn,int64_t stream_id,void * user_data)541 int stream_open(ngtcp2_conn *conn, int64_t stream_id, void *user_data) {
542   auto h = static_cast<Handler *>(user_data);
543   h->on_stream_open(stream_id);
544   return 0;
545 }
546 } // namespace
547 
on_stream_open(int64_t stream_id)548 void Handler::on_stream_open(int64_t stream_id) {
549   if (!ngtcp2_is_bidi_stream(stream_id)) {
550     return;
551   }
552   auto it = streams_.find(stream_id);
553   (void)it;
554   assert(it == std::end(streams_));
555   streams_.emplace(stream_id, std::make_unique<Stream>(stream_id, this));
556 }
557 
558 namespace {
stream_close(ngtcp2_conn * conn,uint32_t flags,int64_t stream_id,uint64_t app_error_code,void * user_data,void * stream_user_data)559 int stream_close(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
560                  uint64_t app_error_code, void *user_data,
561                  void *stream_user_data) {
562   auto h = static_cast<Handler *>(user_data);
563   if (h->on_stream_close(stream_id, app_error_code) != 0) {
564     return NGTCP2_ERR_CALLBACK_FAILURE;
565   }
566   return 0;
567 }
568 } // namespace
569 
570 namespace {
rand(uint8_t * dest,size_t destlen,const ngtcp2_rand_ctx * rand_ctx)571 void rand(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx) {
572   auto dis = std::uniform_int_distribution<uint8_t>(0, 255);
573   std::generate(dest, dest + destlen, [&dis]() { return dis(randgen); });
574 }
575 } // namespace
576 
577 namespace {
get_new_connection_id(ngtcp2_conn * conn,ngtcp2_cid * cid,uint8_t * token,size_t cidlen,void * user_data)578 int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token,
579                           size_t cidlen, void *user_data) {
580   if (util::generate_secure_random(cid->data, cidlen) != 0) {
581     return NGTCP2_ERR_CALLBACK_FAILURE;
582   }
583 
584   cid->datalen = cidlen;
585   if (ngtcp2_crypto_generate_stateless_reset_token(
586           token, config.static_secret.data(), config.static_secret.size(),
587           cid) != 0) {
588     return NGTCP2_ERR_CALLBACK_FAILURE;
589   }
590 
591   auto h = static_cast<Handler *>(user_data);
592   h->server()->associate_cid(cid, h);
593 
594   return 0;
595 }
596 } // namespace
597 
598 namespace {
remove_connection_id(ngtcp2_conn * conn,const ngtcp2_cid * cid,void * user_data)599 int remove_connection_id(ngtcp2_conn *conn, const ngtcp2_cid *cid,
600                          void *user_data) {
601   auto h = static_cast<Handler *>(user_data);
602   h->server()->dissociate_cid(cid);
603   return 0;
604 }
605 } // namespace
606 
607 namespace {
update_key(ngtcp2_conn * conn,uint8_t * rx_secret,uint8_t * tx_secret,ngtcp2_crypto_aead_ctx * rx_aead_ctx,uint8_t * rx_iv,ngtcp2_crypto_aead_ctx * tx_aead_ctx,uint8_t * tx_iv,const uint8_t * current_rx_secret,const uint8_t * current_tx_secret,size_t secretlen,void * user_data)608 int update_key(ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
609                ngtcp2_crypto_aead_ctx *rx_aead_ctx, uint8_t *rx_iv,
610                ngtcp2_crypto_aead_ctx *tx_aead_ctx, uint8_t *tx_iv,
611                const uint8_t *current_rx_secret,
612                const uint8_t *current_tx_secret, size_t secretlen,
613                void *user_data) {
614   auto h = static_cast<Handler *>(user_data);
615   if (h->update_key(rx_secret, tx_secret, rx_aead_ctx, rx_iv, tx_aead_ctx,
616                     tx_iv, current_rx_secret, current_tx_secret,
617                     secretlen) != 0) {
618     return NGTCP2_ERR_CALLBACK_FAILURE;
619   }
620   return 0;
621 }
622 } // namespace
623 
624 namespace {
path_validation(ngtcp2_conn * conn,uint32_t flags,const ngtcp2_path * path,ngtcp2_path_validation_result res,void * user_data)625 int path_validation(ngtcp2_conn *conn, uint32_t flags, const ngtcp2_path *path,
626                     ngtcp2_path_validation_result res, void *user_data) {
627   if (!config.quiet) {
628     debug::path_validation(path, res);
629   }
630   return 0;
631 }
632 } // namespace
633 
634 namespace {
extend_max_stream_data(ngtcp2_conn * conn,int64_t stream_id,uint64_t max_data,void * user_data,void * stream_user_data)635 int extend_max_stream_data(ngtcp2_conn *conn, int64_t stream_id,
636                            uint64_t max_data, void *user_data,
637                            void *stream_user_data) {
638   auto h = static_cast<Handler *>(user_data);
639   if (h->extend_max_stream_data(stream_id, max_data) != 0) {
640     return NGTCP2_ERR_CALLBACK_FAILURE;
641   }
642   return 0;
643 }
644 } // namespace
645 
extend_max_stream_data(int64_t stream_id,uint64_t max_data)646 int Handler::extend_max_stream_data(int64_t stream_id, uint64_t max_data) {
647   auto it = streams_.find(stream_id);
648   assert(it != std::end(streams_));
649   auto &stream = (*it).second;
650 
651   if (nghttp3_buf_len(&stream->respbuf)) {
652     sendq_.emplace(stream.get());
653   }
654 
655   return 0;
656 }
657 
658 namespace {
write_qlog(void * user_data,uint32_t flags,const void * data,size_t datalen)659 void write_qlog(void *user_data, uint32_t flags, const void *data,
660                 size_t datalen) {
661   auto h = static_cast<Handler *>(user_data);
662   h->write_qlog(data, datalen);
663 }
664 } // namespace
665 
write_qlog(const void * data,size_t datalen)666 void Handler::write_qlog(const void *data, size_t datalen) {
667   assert(qlog_);
668   fwrite(data, 1, datalen, qlog_);
669 }
670 
init(const Endpoint & ep,const Address & local_addr,const sockaddr * sa,socklen_t salen,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,const ngtcp2_cid * ocid,const uint8_t * token,size_t tokenlen,uint32_t version,const TLSServerContext & tls_ctx)671 int Handler::init(const Endpoint &ep, const Address &local_addr,
672                   const sockaddr *sa, socklen_t salen, const ngtcp2_cid *dcid,
673                   const ngtcp2_cid *scid, const ngtcp2_cid *ocid,
674                   const uint8_t *token, size_t tokenlen, uint32_t version,
675                   const TLSServerContext &tls_ctx) {
676   auto callbacks = ngtcp2_callbacks{
677       nullptr, // client_initial
678       ngtcp2_crypto_recv_client_initial_cb,
679       ::recv_crypto_data,
680       ::handshake_completed,
681       nullptr, // recv_version_negotiation
682       ngtcp2_crypto_encrypt_cb,
683       ngtcp2_crypto_decrypt_cb,
684       do_hp_mask,
685       ::recv_stream_data,
686       ::acked_stream_data_offset,
687       stream_open,
688       stream_close,
689       nullptr, // recv_stateless_reset
690       nullptr, // recv_retry
691       nullptr, // extend_max_streams_bidi
692       nullptr, // extend_max_streams_uni
693       rand,
694       get_new_connection_id,
695       remove_connection_id,
696       ::update_key,
697       path_validation,
698       nullptr, // select_preferred_addr
699       nullptr, // stream_reset
700       nullptr, // extend_max_remote_streams_bidi
701       nullptr, // extend_max_remote_streams_uni
702       ::extend_max_stream_data,
703       nullptr, // dcid_status
704       nullptr, // handshake_confirmed
705       nullptr, // recv_new_token
706       ngtcp2_crypto_delete_crypto_aead_ctx_cb,
707       ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
708       nullptr, // recv_datagram
709       nullptr, // ack_datagram
710       nullptr, // lost_datagram
711       ngtcp2_crypto_get_path_challenge_data_cb,
712   };
713 
714   scid_.datalen = NGTCP2_SV_SCIDLEN;
715   if (util::generate_secure_random(scid_.data, scid_.datalen) != 0) {
716     std::cerr << "Could not generate connection ID" << std::endl;
717     return -1;
718   }
719 
720   ngtcp2_settings settings;
721   ngtcp2_settings_default(&settings);
722   settings.log_printf = config.quiet ? nullptr : debug::log_printf;
723   settings.initial_ts = util::timestamp(loop_);
724   settings.token = ngtcp2_vec{const_cast<uint8_t *>(token), tokenlen};
725   settings.cc_algo = config.cc_algo;
726   settings.initial_rtt = config.initial_rtt;
727   if (config.max_udp_payload_size) {
728     settings.max_udp_payload_size = config.max_udp_payload_size;
729     settings.no_udp_payload_size_shaping = 1;
730   } else {
731     settings.max_udp_payload_size = server_max_udp_payload_size;
732     settings.assume_symmetric_path = 1;
733   }
734   if (!config.qlog_dir.empty()) {
735     auto path = std::string{config.qlog_dir};
736     path += '/';
737     path += util::format_hex(scid_.data, scid_.datalen);
738     path += ".sqlog";
739     qlog_ = fopen(path.c_str(), "w");
740     if (qlog_ == nullptr) {
741       std::cerr << "Could not open qlog file " << std::quoted(path) << ": "
742                 << strerror(errno) << std::endl;
743       return -1;
744     }
745     settings.qlog.write = ::write_qlog;
746     settings.qlog.odcid = *scid;
747   }
748 
749   ngtcp2_transport_params params;
750   ngtcp2_transport_params_default(&params);
751   params.initial_max_stream_data_bidi_local = config.max_stream_data_bidi_local;
752   params.initial_max_stream_data_bidi_remote =
753       config.max_stream_data_bidi_remote;
754   params.initial_max_stream_data_uni = config.max_stream_data_uni;
755   params.initial_max_data = config.max_data;
756   params.initial_max_streams_bidi = config.max_streams_bidi;
757   params.initial_max_streams_uni = 0;
758   params.max_idle_timeout = config.timeout;
759   params.stateless_reset_token_present = 1;
760   params.active_connection_id_limit = 7;
761 
762   if (ocid) {
763     params.original_dcid = *ocid;
764     params.retry_scid = *scid;
765     params.retry_scid_present = 1;
766   } else {
767     params.original_dcid = *scid;
768   }
769 
770   if (util::generate_secure_random(params.stateless_reset_token,
771                                    sizeof(params.stateless_reset_token)) != 0) {
772     std::cerr << "Could not generate stateless reset token" << std::endl;
773     return -1;
774   }
775 
776   if (config.preferred_ipv4_addr.len || config.preferred_ipv6_addr.len) {
777     params.preferred_address_present = 1;
778     if (config.preferred_ipv4_addr.len) {
779       auto &dest = params.preferred_address.ipv4_addr;
780       const auto &addr = config.preferred_ipv4_addr;
781       assert(sizeof(dest) == sizeof(addr.su.in.sin_addr));
782       memcpy(&dest, &addr.su.in.sin_addr, sizeof(dest));
783       params.preferred_address.ipv4_port = htons(addr.su.in.sin_port);
784       params.preferred_address.ipv4_present = 1;
785     }
786     if (config.preferred_ipv6_addr.len) {
787       auto &dest = params.preferred_address.ipv6_addr;
788       const auto &addr = config.preferred_ipv6_addr;
789       assert(sizeof(dest) == sizeof(addr.su.in6.sin6_addr));
790       memcpy(&dest, &addr.su.in6.sin6_addr, sizeof(dest));
791       params.preferred_address.ipv6_port = htons(addr.su.in6.sin6_port);
792       params.preferred_address.ipv6_present = 1;
793     }
794 
795     auto &token = params.preferred_address.stateless_reset_token;
796     if (util::generate_secure_random(token, sizeof(token)) != 0) {
797       std::cerr << "Could not generate preferred address stateless reset token"
798                 << std::endl;
799       return -1;
800     }
801 
802     params.preferred_address.cid.datalen = NGTCP2_SV_SCIDLEN;
803     if (util::generate_secure_random(params.preferred_address.cid.data,
804                                      params.preferred_address.cid.datalen) !=
805         0) {
806       std::cerr << "Could not generate preferred address connection ID"
807                 << std::endl;
808       return -1;
809     }
810   }
811 
812   auto path = ngtcp2_path{
813       {
814           const_cast<sockaddr *>(&local_addr.su.sa),
815           local_addr.len,
816       },
817       {
818           const_cast<sockaddr *>(sa),
819           salen,
820       },
821       const_cast<Endpoint *>(&ep),
822   };
823   if (auto rv =
824           ngtcp2_conn_server_new(&conn_, dcid, &scid_, &path, version,
825                                  &callbacks, &settings, &params, nullptr, this);
826       rv != 0) {
827     std::cerr << "ngtcp2_conn_server_new: " << ngtcp2_strerror(rv) << std::endl;
828     return -1;
829   }
830 
831   if (tls_session_.init(tls_ctx, this) != 0) {
832     return -1;
833   }
834 
835   tls_session_.enable_keylog();
836 
837   ngtcp2_conn_set_tls_native_handle(conn_, tls_session_.get_native_handle());
838 
839   ev_io_set(&wev_, ep.fd, EV_WRITE);
840   ev_timer_again(loop_, &timer_);
841 
842   return 0;
843 }
844 
feed_data(const Endpoint & ep,const Address & local_addr,const sockaddr * sa,socklen_t salen,const ngtcp2_pkt_info * pi,uint8_t * data,size_t datalen)845 int Handler::feed_data(const Endpoint &ep, const Address &local_addr,
846                        const sockaddr *sa, socklen_t salen,
847                        const ngtcp2_pkt_info *pi, uint8_t *data,
848                        size_t datalen) {
849   auto path = ngtcp2_path{
850       {
851           const_cast<sockaddr *>(&local_addr.su.sa),
852           local_addr.len,
853       },
854       {
855           const_cast<sockaddr *>(sa),
856           salen,
857       },
858       const_cast<Endpoint *>(&ep),
859   };
860 
861   if (auto rv = ngtcp2_conn_read_pkt(conn_, &path, pi, data, datalen,
862                                      util::timestamp(loop_));
863       rv != 0) {
864     std::cerr << "ngtcp2_conn_read_pkt: " << ngtcp2_strerror(rv) << std::endl;
865     switch (rv) {
866     case NGTCP2_ERR_DRAINING:
867       start_draining_period();
868       return NETWORK_ERR_CLOSE_WAIT;
869     case NGTCP2_ERR_RETRY:
870       return NETWORK_ERR_RETRY;
871     case NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM:
872     case NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM:
873     case NGTCP2_ERR_TRANSPORT_PARAM:
874       // If rv indicates transport_parameters related error, we should
875       // send TRANSPORT_PARAMETER_ERROR even if last_error_.code is
876       // already set.  This is because OpenSSL might set Alert.
877       last_error_ = quic_err_transport(rv);
878       break;
879     case NGTCP2_ERR_DROP_CONN:
880       return NETWORK_ERR_DROP_CONN;
881     default:
882       if (!last_error_.code) {
883         last_error_ = quic_err_transport(rv);
884       }
885     }
886     return handle_error();
887   }
888 
889   return 0;
890 }
891 
on_read(const Endpoint & ep,const Address & local_addr,const sockaddr * sa,socklen_t salen,const ngtcp2_pkt_info * pi,uint8_t * data,size_t datalen)892 int Handler::on_read(const Endpoint &ep, const Address &local_addr,
893                      const sockaddr *sa, socklen_t salen,
894                      const ngtcp2_pkt_info *pi, uint8_t *data, size_t datalen) {
895   if (auto rv = feed_data(ep, local_addr, sa, salen, pi, data, datalen);
896       rv != 0) {
897     return rv;
898   }
899 
900   reset_idle_timer();
901 
902   return 0;
903 }
904 
reset_idle_timer()905 void Handler::reset_idle_timer() {
906   auto now = util::timestamp(loop_);
907   auto idle_expiry = ngtcp2_conn_get_idle_expiry(conn_);
908   timer_.repeat =
909       idle_expiry > now
910           ? static_cast<ev_tstamp>(idle_expiry - now) / NGTCP2_SECONDS
911           : 1e-9;
912 
913   if (!config.quiet) {
914     std::cerr << "Set idle timer=" << std::fixed << timer_.repeat << "s"
915               << std::defaultfloat << std::endl;
916   }
917 
918   ev_timer_again(loop_, &timer_);
919 }
920 
handle_expiry()921 int Handler::handle_expiry() {
922   auto now = util::timestamp(loop_);
923   if (auto rv = ngtcp2_conn_handle_expiry(conn_, now); rv != 0) {
924     std::cerr << "ngtcp2_conn_handle_expiry: " << ngtcp2_strerror(rv)
925               << std::endl;
926     last_error_ = quic_err_transport(rv);
927     return handle_error();
928   }
929 
930   return 0;
931 }
932 
on_write()933 int Handler::on_write() {
934   if (ngtcp2_conn_is_in_closing_period(conn_) ||
935       ngtcp2_conn_is_in_draining_period(conn_)) {
936     return 0;
937   }
938 
939   if (auto rv = write_streams(); rv != 0) {
940     return rv;
941   }
942 
943   schedule_retransmit();
944 
945   return 0;
946 }
947 
write_streams()948 int Handler::write_streams() {
949   ngtcp2_vec vec;
950   ngtcp2_path_storage ps, prev_ps;
951   uint32_t prev_ecn = 0;
952   size_t pktcnt = 0;
953   auto max_udp_payload_size = ngtcp2_conn_get_path_max_udp_payload_size(conn_);
954   size_t max_pktcnt =
955       std::min(static_cast<size_t>(64_k), ngtcp2_conn_get_send_quantum(conn_)) /
956       max_udp_payload_size;
957   std::array<uint8_t, 64_k> buf;
958   uint8_t *bufpos = buf.data();
959   ngtcp2_pkt_info pi;
960   auto ts = util::timestamp(loop_);
961 
962   ngtcp2_path_storage_zero(&ps);
963   ngtcp2_path_storage_zero(&prev_ps);
964 
965   if (config.cc_algo != NGTCP2_CC_ALGO_BBR) {
966     /* If bbr is chosen, pacing is enabled.  No need to cap the number
967        of datagrams to send. */
968     max_pktcnt =
969         std::min(max_pktcnt, static_cast<size_t>(config.max_gso_dgrams));
970   }
971 
972   for (;;) {
973     int64_t stream_id = -1;
974     size_t vcnt = 0;
975     uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE;
976     Stream *stream = nullptr;
977 
978     if (!sendq_.empty() && ngtcp2_conn_get_max_data_left(conn_)) {
979       stream = *std::begin(sendq_);
980 
981       stream_id = stream->stream_id;
982       vec.base = stream->respbuf.pos;
983       vec.len = nghttp3_buf_len(&stream->respbuf);
984       vcnt = 1;
985       flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
986     }
987 
988     ngtcp2_ssize ndatalen;
989 
990     auto nwrite = ngtcp2_conn_writev_stream(conn_, &ps.path, &pi, bufpos,
991                                             max_udp_payload_size, &ndatalen,
992                                             flags, stream_id, &vec, vcnt, ts);
993     if (nwrite < 0) {
994       switch (nwrite) {
995       case NGTCP2_ERR_STREAM_DATA_BLOCKED:
996       case NGTCP2_ERR_STREAM_SHUT_WR:
997         assert(ndatalen == -1);
998         sendq_.erase(std::begin(sendq_));
999         continue;
1000       case NGTCP2_ERR_WRITE_MORE:
1001         assert(ndatalen >= 0);
1002         stream->respbuf.pos += ndatalen;
1003         if (nghttp3_buf_len(&stream->respbuf) == 0) {
1004           sendq_.erase(std::begin(sendq_));
1005         }
1006         continue;
1007       }
1008 
1009       assert(ndatalen == -1);
1010 
1011       std::cerr << "ngtcp2_conn_writev_stream: " << ngtcp2_strerror(nwrite)
1012                 << std::endl;
1013       last_error_ = quic_err_transport(nwrite);
1014       return handle_error();
1015     } else if (ndatalen >= 0) {
1016       stream->respbuf.pos += ndatalen;
1017       if (nghttp3_buf_len(&stream->respbuf) == 0) {
1018         sendq_.erase(std::begin(sendq_));
1019       }
1020     }
1021 
1022     if (nwrite == 0) {
1023       if (bufpos - buf.data()) {
1024         server_->send_packet(*static_cast<Endpoint *>(prev_ps.path.user_data),
1025                              prev_ps.path.local, prev_ps.path.remote, prev_ecn,
1026                              buf.data(), bufpos - buf.data(),
1027                              max_udp_payload_size);
1028         reset_idle_timer();
1029       }
1030       // We are congestion limited.
1031       ngtcp2_conn_update_pkt_tx_time(conn_, ts);
1032       return 0;
1033     }
1034 
1035     bufpos += nwrite;
1036 
1037 #if NGTCP2_ENABLE_UDP_GSO
1038     if (pktcnt == 0) {
1039       ngtcp2_path_copy(&prev_ps.path, &ps.path);
1040       prev_ecn = pi.ecn;
1041     } else if (!ngtcp2_path_eq(&prev_ps.path, &ps.path) || prev_ecn != pi.ecn) {
1042       server_->send_packet(*static_cast<Endpoint *>(prev_ps.path.user_data),
1043                            prev_ps.path.local, prev_ps.path.remote, prev_ecn,
1044                            buf.data(), bufpos - buf.data() - nwrite,
1045                            max_udp_payload_size);
1046 
1047       server_->send_packet(*static_cast<Endpoint *>(ps.path.user_data),
1048                            ps.path.local, ps.path.remote, pi.ecn,
1049                            bufpos - nwrite, nwrite, max_udp_payload_size);
1050       ngtcp2_conn_update_pkt_tx_time(conn_, ts);
1051       reset_idle_timer();
1052       ev_io_start(loop_, &wev_);
1053       return 0;
1054     }
1055 
1056     if (++pktcnt == max_pktcnt ||
1057         static_cast<size_t>(nwrite) < max_udp_payload_size) {
1058       server_->send_packet(*static_cast<Endpoint *>(ps.path.user_data),
1059                            ps.path.local, ps.path.remote, pi.ecn, buf.data(),
1060                            bufpos - buf.data(), max_udp_payload_size);
1061       ngtcp2_conn_update_pkt_tx_time(conn_, ts);
1062       reset_idle_timer();
1063       ev_io_start(loop_, &wev_);
1064       return 0;
1065     }
1066 #else  // !NGTCP2_ENABLE_UDP_GSO
1067     reset_idle_timer();
1068 
1069     server_->send_packet(*static_cast<Endpoint *>(ps.path.user_data),
1070                          ps.path.local, ps.path.remote, pi.ecn, buf.data(),
1071                          bufpos - buf.data(), 0);
1072     if (++pktcnt == max_pktcnt) {
1073       ngtcp2_conn_update_pkt_tx_time(conn_, ts);
1074       ev_io_start(loop_, &wev_);
1075       return 0;
1076     }
1077 
1078     bufpos = buf.data();
1079 #endif // !NGTCP2_ENABLE_UDP_GSO
1080   }
1081 }
1082 
signal_write()1083 void Handler::signal_write() { ev_io_start(loop_, &wev_); }
1084 
draining() const1085 bool Handler::draining() const { return draining_; }
1086 
start_draining_period()1087 void Handler::start_draining_period() {
1088   draining_ = true;
1089 
1090   ev_timer_stop(loop_, &rttimer_);
1091 
1092   timer_.repeat =
1093       static_cast<ev_tstamp>(ngtcp2_conn_get_pto(conn_)) / NGTCP2_SECONDS * 3;
1094   ev_timer_again(loop_, &timer_);
1095 
1096   if (!config.quiet) {
1097     std::cerr << "Draining period has started (" << timer_.repeat << " seconds)"
1098               << std::endl;
1099   }
1100 }
1101 
start_closing_period()1102 int Handler::start_closing_period() {
1103   if (!conn_ || ngtcp2_conn_is_in_closing_period(conn_)) {
1104     return 0;
1105   }
1106 
1107   ev_timer_stop(loop_, &rttimer_);
1108 
1109   timer_.repeat =
1110       static_cast<ev_tstamp>(ngtcp2_conn_get_pto(conn_)) / NGTCP2_SECONDS * 3;
1111   ev_timer_again(loop_, &timer_);
1112 
1113   if (!config.quiet) {
1114     std::cerr << "Closing period has started (" << timer_.repeat << " seconds)"
1115               << std::endl;
1116   }
1117 
1118   conn_closebuf_ = std::make_unique<Buffer>(NGTCP2_MAX_UDP_PAYLOAD_SIZE);
1119 
1120   ngtcp2_path_storage ps;
1121 
1122   ngtcp2_path_storage_zero(&ps);
1123 
1124   ngtcp2_pkt_info pi;
1125   if (last_error_.type == QUICErrorType::Transport) {
1126     auto n = ngtcp2_conn_write_connection_close(
1127         conn_, &ps.path, &pi, conn_closebuf_->wpos(), conn_closebuf_->left(),
1128         last_error_.code, util::timestamp(loop_));
1129     if (n < 0) {
1130       std::cerr << "ngtcp2_conn_write_connection_close: " << ngtcp2_strerror(n)
1131                 << std::endl;
1132       return -1;
1133     }
1134     conn_closebuf_->push(n);
1135   } else {
1136     auto n = ngtcp2_conn_write_application_close(
1137         conn_, &ps.path, &pi, conn_closebuf_->wpos(), conn_closebuf_->left(),
1138         last_error_.code, util::timestamp(loop_));
1139     if (n < 0) {
1140       std::cerr << "ngtcp2_conn_write_application_close: " << ngtcp2_strerror(n)
1141                 << std::endl;
1142       return -1;
1143     }
1144     conn_closebuf_->push(n);
1145   }
1146 
1147   return 0;
1148 }
1149 
handle_error()1150 int Handler::handle_error() {
1151   if (start_closing_period() != 0) {
1152     return -1;
1153   }
1154 
1155   if (auto rv = send_conn_close(); rv != NETWORK_ERR_OK) {
1156     return rv;
1157   }
1158 
1159   return NETWORK_ERR_CLOSE_WAIT;
1160 }
1161 
send_conn_close()1162 int Handler::send_conn_close() {
1163   if (!config.quiet) {
1164     std::cerr << "Closing Period: TX CONNECTION_CLOSE" << std::endl;
1165   }
1166 
1167   assert(conn_closebuf_ && conn_closebuf_->size());
1168   assert(conn_);
1169 
1170   auto path = ngtcp2_conn_get_path(conn_);
1171 
1172   return server_->send_packet(
1173       *static_cast<Endpoint *>(path->user_data), path->local, path->remote,
1174       /* ecn = */ 0, conn_closebuf_->rpos(), conn_closebuf_->size(), 0);
1175 }
1176 
schedule_retransmit()1177 void Handler::schedule_retransmit() {
1178   auto expiry = ngtcp2_conn_get_expiry(conn_);
1179   auto now = util::timestamp(loop_);
1180   auto t = expiry < now ? 1e-9
1181                         : static_cast<ev_tstamp>(expiry - now) / NGTCP2_SECONDS;
1182   if (!config.quiet) {
1183     std::cerr << "Set timer=" << std::fixed << t << "s" << std::defaultfloat
1184               << std::endl;
1185   }
1186   rttimer_.repeat = t;
1187   ev_timer_again(loop_, &rttimer_);
1188 }
1189 
1190 namespace {
on_msg_begin(http_parser * htp)1191 int on_msg_begin(http_parser *htp) {
1192   auto s = static_cast<Stream *>(htp->data);
1193   if (s->eos) {
1194     return -1;
1195   }
1196   return 0;
1197 }
1198 } // namespace
1199 
1200 namespace {
on_url_cb(http_parser * htp,const char * data,size_t datalen)1201 int on_url_cb(http_parser *htp, const char *data, size_t datalen) {
1202   auto s = static_cast<Stream *>(htp->data);
1203   s->uri.append(data, datalen);
1204   return 0;
1205 }
1206 } // namespace
1207 
1208 namespace {
on_msg_complete(http_parser * htp)1209 int on_msg_complete(http_parser *htp) {
1210   auto s = static_cast<Stream *>(htp->data);
1211   s->eos = true;
1212   if (s->start_response() != 0) {
1213     return -1;
1214   }
1215   return 0;
1216 }
1217 } // namespace
1218 
1219 auto htp_settings = http_parser_settings{
1220     on_msg_begin,    // on_message_begin
1221     on_url_cb,       // on_url
1222     nullptr,         // on_status
1223     nullptr,         // on_header_field
1224     nullptr,         // on_header_value
1225     nullptr,         // on_headers_complete
1226     nullptr,         // on_body
1227     on_msg_complete, // on_message_complete
1228     nullptr,         // on_chunk_header,
1229     nullptr,         // on_chunk_complete
1230 };
1231 
recv_stream_data(uint32_t flags,int64_t stream_id,const uint8_t * data,size_t datalen)1232 int Handler::recv_stream_data(uint32_t flags, int64_t stream_id,
1233                               const uint8_t *data, size_t datalen) {
1234   if (!config.quiet && !config.no_quic_dump) {
1235     debug::print_stream_data(stream_id, data, datalen);
1236   }
1237 
1238   auto it = streams_.find(stream_id);
1239   assert(it != std::end(streams_));
1240   auto &stream = (*it).second;
1241 
1242   if (!stream->eos) {
1243     auto nread =
1244         http_parser_execute(&stream->htp, &htp_settings,
1245                             reinterpret_cast<const char *>(data), datalen);
1246     if (nread != datalen) {
1247       if (auto rv = ngtcp2_conn_shutdown_stream(conn_, stream_id,
1248                                                 /* app error code */ 1);
1249           rv != 0) {
1250         std::cerr << "ngtcp2_conn_shutdown_stream: " << ngtcp2_strerror(rv)
1251                   << std::endl;
1252         last_error_ = quic_err_transport(NGTCP2_ERR_INTERNAL);
1253         return -1;
1254       }
1255     }
1256   }
1257 
1258   ngtcp2_conn_extend_max_stream_offset(conn_, stream_id, datalen);
1259   ngtcp2_conn_extend_max_offset(conn_, datalen);
1260 
1261   return 0;
1262 }
1263 
update_key(uint8_t * rx_secret,uint8_t * tx_secret,ngtcp2_crypto_aead_ctx * rx_aead_ctx,uint8_t * rx_iv,ngtcp2_crypto_aead_ctx * tx_aead_ctx,uint8_t * tx_iv,const uint8_t * current_rx_secret,const uint8_t * current_tx_secret,size_t secretlen)1264 int Handler::update_key(uint8_t *rx_secret, uint8_t *tx_secret,
1265                         ngtcp2_crypto_aead_ctx *rx_aead_ctx, uint8_t *rx_iv,
1266                         ngtcp2_crypto_aead_ctx *tx_aead_ctx, uint8_t *tx_iv,
1267                         const uint8_t *current_rx_secret,
1268                         const uint8_t *current_tx_secret, size_t secretlen) {
1269   auto crypto_ctx = ngtcp2_conn_get_crypto_ctx(conn_);
1270   auto aead = &crypto_ctx->aead;
1271   auto keylen = ngtcp2_crypto_aead_keylen(aead);
1272   auto ivlen = ngtcp2_crypto_packet_protection_ivlen(aead);
1273 
1274   ++nkey_update_;
1275 
1276   std::array<uint8_t, 64> rx_key, tx_key;
1277 
1278   if (ngtcp2_crypto_update_key(conn_, rx_secret, tx_secret, rx_aead_ctx,
1279                                rx_key.data(), rx_iv, tx_aead_ctx, tx_key.data(),
1280                                tx_iv, current_rx_secret, current_tx_secret,
1281                                secretlen) != 0) {
1282     return -1;
1283   }
1284 
1285   if (!config.quiet && config.show_secret) {
1286     std::cerr << "application_traffic rx secret " << nkey_update_ << std::endl;
1287     debug::print_secrets(rx_secret, secretlen, rx_key.data(), keylen, rx_iv,
1288                          ivlen);
1289     std::cerr << "application_traffic tx secret " << nkey_update_ << std::endl;
1290     debug::print_secrets(tx_secret, secretlen, tx_key.data(), keylen, tx_iv,
1291                          ivlen);
1292   }
1293 
1294   return 0;
1295 }
1296 
server() const1297 Server *Handler::server() const { return server_; }
1298 
on_stream_close(int64_t stream_id,uint64_t app_error_code)1299 int Handler::on_stream_close(int64_t stream_id, uint64_t app_error_code) {
1300   if (!config.quiet) {
1301     std::cerr << "QUIC stream " << stream_id << " closed" << std::endl;
1302   }
1303 
1304   auto it = streams_.find(stream_id);
1305   assert(it != std::end(streams_));
1306   auto &stream = (*it).second;
1307 
1308   sendq_.erase(stream.get());
1309 
1310   if (!config.quiet) {
1311     std::cerr << "HTTP stream " << stream_id << " closed with error code "
1312               << app_error_code << std::endl;
1313   }
1314 
1315   streams_.erase(it);
1316 
1317   if (ngtcp2_is_bidi_stream(stream_id)) {
1318     assert(!ngtcp2_conn_is_local_stream(conn_, stream_id));
1319     ngtcp2_conn_extend_max_streams_bidi(conn_, 1);
1320   }
1321 
1322   return 0;
1323 }
1324 
shutdown_read(int64_t stream_id,int app_error_code)1325 void Handler::shutdown_read(int64_t stream_id, int app_error_code) {
1326   ngtcp2_conn_shutdown_stream_read(conn_, stream_id, app_error_code);
1327 }
1328 
add_sendq(Stream * stream)1329 void Handler::add_sendq(Stream *stream) { sendq_.emplace(stream); }
1330 
1331 namespace {
sreadcb(struct ev_loop * loop,ev_io * w,int revents)1332 void sreadcb(struct ev_loop *loop, ev_io *w, int revents) {
1333   auto ep = static_cast<Endpoint *>(w->data);
1334 
1335   ep->server->on_read(*ep);
1336 }
1337 } // namespace
1338 
1339 namespace {
siginthandler(struct ev_loop * loop,ev_signal * watcher,int revents)1340 void siginthandler(struct ev_loop *loop, ev_signal *watcher, int revents) {
1341   ev_break(loop, EVBREAK_ALL);
1342 }
1343 } // namespace
1344 
Server(struct ev_loop * loop,const TLSServerContext & tls_ctx)1345 Server::Server(struct ev_loop *loop, const TLSServerContext &tls_ctx)
1346     : loop_(loop), tls_ctx_(tls_ctx) {
1347   ev_signal_init(&sigintev_, siginthandler, SIGINT);
1348 }
1349 
~Server()1350 Server::~Server() {
1351   disconnect();
1352   close();
1353 }
1354 
disconnect()1355 void Server::disconnect() {
1356   config.tx_loss_prob = 0;
1357 
1358   for (auto &ep : endpoints_) {
1359     ev_io_stop(loop_, &ep.rev);
1360   }
1361 
1362   ev_signal_stop(loop_, &sigintev_);
1363 
1364   while (!handlers_.empty()) {
1365     auto it = std::begin(handlers_);
1366     auto &h = (*it).second;
1367 
1368     h->handle_error();
1369 
1370     remove(h);
1371   }
1372 }
1373 
close()1374 void Server::close() {
1375   for (auto &ep : endpoints_) {
1376     ::close(ep.fd);
1377   }
1378 
1379   endpoints_.clear();
1380 }
1381 
1382 namespace {
create_sock(Address & local_addr,const char * addr,const char * port,int family)1383 int create_sock(Address &local_addr, const char *addr, const char *port,
1384                 int family) {
1385   addrinfo hints{};
1386   addrinfo *res, *rp;
1387   int val = 1;
1388 
1389   hints.ai_family = family;
1390   hints.ai_socktype = SOCK_DGRAM;
1391   hints.ai_flags = AI_PASSIVE;
1392 
1393   if (strcmp(addr, "*") == 0) {
1394     addr = nullptr;
1395   }
1396 
1397   if (auto rv = getaddrinfo(addr, port, &hints, &res); rv != 0) {
1398     std::cerr << "getaddrinfo: " << gai_strerror(rv) << std::endl;
1399     return -1;
1400   }
1401 
1402   auto res_d = defer(freeaddrinfo, res);
1403 
1404   int fd = -1;
1405 
1406   for (rp = res; rp; rp = rp->ai_next) {
1407     fd = util::create_nonblock_socket(rp->ai_family, rp->ai_socktype,
1408                                       rp->ai_protocol);
1409     if (fd == -1) {
1410       continue;
1411     }
1412 
1413     if (rp->ai_family == AF_INET6) {
1414       if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1415                      static_cast<socklen_t>(sizeof(val))) == -1) {
1416         close(fd);
1417         continue;
1418       }
1419 
1420       if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
1421                      static_cast<socklen_t>(sizeof(val))) == -1) {
1422         close(fd);
1423         continue;
1424       }
1425     } else if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &val,
1426                           static_cast<socklen_t>(sizeof(val))) == -1) {
1427       close(fd);
1428       continue;
1429     }
1430 
1431     if (bind(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
1432       break;
1433     }
1434 
1435     close(fd);
1436   }
1437 
1438   if (!rp) {
1439     std::cerr << "Could not bind" << std::endl;
1440     return -1;
1441   }
1442 
1443   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
1444                  static_cast<socklen_t>(sizeof(val))) == -1) {
1445     close(fd);
1446     return -1;
1447   }
1448 
1449   fd_set_recv_ecn(fd, rp->ai_family);
1450 
1451   socklen_t len = sizeof(local_addr.su.storage);
1452   if (getsockname(fd, &local_addr.su.sa, &len) == -1) {
1453     std::cerr << "getsockname: " << strerror(errno) << std::endl;
1454     close(fd);
1455     return -1;
1456   }
1457   local_addr.len = len;
1458   local_addr.ifindex = 0;
1459 
1460   return fd;
1461 }
1462 
1463 } // namespace
1464 
1465 namespace {
add_endpoint(std::vector<Endpoint> & endpoints,const char * addr,const char * port,int af)1466 int add_endpoint(std::vector<Endpoint> &endpoints, const char *addr,
1467                  const char *port, int af) {
1468   Address dest;
1469   auto fd = create_sock(dest, addr, port, af);
1470   if (fd == -1) {
1471     return -1;
1472   }
1473 
1474   endpoints.emplace_back();
1475   auto &ep = endpoints.back();
1476   ep.addr = dest;
1477   ep.fd = fd;
1478   ev_io_init(&ep.rev, sreadcb, 0, EV_READ);
1479 
1480   return 0;
1481 }
1482 } // namespace
1483 
1484 namespace {
add_endpoint(std::vector<Endpoint> & endpoints,const Address & addr)1485 int add_endpoint(std::vector<Endpoint> &endpoints, const Address &addr) {
1486   auto fd = util::create_nonblock_socket(addr.su.sa.sa_family, SOCK_DGRAM, 0);
1487   if (fd == -1) {
1488     std::cerr << "socket: " << strerror(errno) << std::endl;
1489     return -1;
1490   }
1491 
1492   int val = 1;
1493   if (addr.su.sa.sa_family == AF_INET6) {
1494     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1495                    static_cast<socklen_t>(sizeof(val))) == -1) {
1496       std::cerr << "setsockopt: " << strerror(errno) << std::endl;
1497       close(fd);
1498       return -1;
1499     }
1500 
1501     if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val,
1502                    static_cast<socklen_t>(sizeof(val))) == -1) {
1503       std::cerr << "setsockopt: " << strerror(errno) << std::endl;
1504       close(fd);
1505       return -1;
1506     }
1507   } else if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &val,
1508                         static_cast<socklen_t>(sizeof(val))) == -1) {
1509     std::cerr << "setsockopt: " << strerror(errno) << std::endl;
1510     close(fd);
1511     return -1;
1512   }
1513 
1514   if (bind(fd, &addr.su.sa, addr.len) == -1) {
1515     std::cerr << "bind: " << strerror(errno) << std::endl;
1516     close(fd);
1517     return -1;
1518   }
1519 
1520   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
1521                  static_cast<socklen_t>(sizeof(val))) == -1) {
1522     close(fd);
1523     return -1;
1524   }
1525 
1526   fd_set_recv_ecn(fd, addr.su.sa.sa_family);
1527 
1528   endpoints.emplace_back(Endpoint{});
1529   auto &ep = endpoints.back();
1530   ep.addr = addr;
1531   ep.fd = fd;
1532   ev_io_init(&ep.rev, sreadcb, 0, EV_READ);
1533 
1534   return 0;
1535 }
1536 } // namespace
1537 
init(const char * addr,const char * port)1538 int Server::init(const char *addr, const char *port) {
1539   endpoints_.reserve(4);
1540 
1541   auto ready = false;
1542   if (!util::numeric_host(addr, AF_INET6) &&
1543       add_endpoint(endpoints_, addr, port, AF_INET) == 0) {
1544     ready = true;
1545   }
1546   if (!util::numeric_host(addr, AF_INET) &&
1547       add_endpoint(endpoints_, addr, port, AF_INET6) == 0) {
1548     ready = true;
1549   }
1550   if (!ready) {
1551     return -1;
1552   }
1553 
1554   if (config.preferred_ipv4_addr.len &&
1555       add_endpoint(endpoints_, config.preferred_ipv4_addr) != 0) {
1556     return -1;
1557   }
1558   if (config.preferred_ipv6_addr.len &&
1559       add_endpoint(endpoints_, config.preferred_ipv6_addr) != 0) {
1560     return -1;
1561   }
1562 
1563   for (auto &ep : endpoints_) {
1564     ep.server = this;
1565     ep.rev.data = &ep;
1566 
1567     ev_io_set(&ep.rev, ep.fd, EV_READ);
1568 
1569     ev_io_start(loop_, &ep.rev);
1570   }
1571 
1572   ev_signal_start(loop_, &sigintev_);
1573 
1574   return 0;
1575 }
1576 
on_read(Endpoint & ep)1577 int Server::on_read(Endpoint &ep) {
1578   sockaddr_union su;
1579   std::array<uint8_t, 64_k> buf;
1580   ngtcp2_pkt_hd hd;
1581   size_t pktcnt = 0;
1582   ngtcp2_pkt_info pi;
1583 
1584   iovec msg_iov;
1585   msg_iov.iov_base = buf.data();
1586   msg_iov.iov_len = buf.size();
1587 
1588   msghdr msg{};
1589   msg.msg_name = &su;
1590   msg.msg_iov = &msg_iov;
1591   msg.msg_iovlen = 1;
1592 
1593   uint8_t
1594       msg_ctrl[CMSG_SPACE(sizeof(uint8_t)) + CMSG_SPACE(sizeof(in6_pktinfo))];
1595   msg.msg_control = msg_ctrl;
1596 
1597   for (; pktcnt < 10;) {
1598     msg.msg_namelen = sizeof(su);
1599     msg.msg_controllen = sizeof(msg_ctrl);
1600 
1601     auto nread = recvmsg(ep.fd, &msg, 0);
1602     if (nread == -1) {
1603       if (!(errno == EAGAIN || errno == ENOTCONN)) {
1604         std::cerr << "recvmsg: " << strerror(errno) << std::endl;
1605       }
1606       return 0;
1607     }
1608 
1609     ++pktcnt;
1610 
1611     pi.ecn = msghdr_get_ecn(&msg, su.storage.ss_family);
1612     auto local_addr = msghdr_get_local_addr(&msg, su.storage.ss_family);
1613     if (!local_addr) {
1614       std::cerr << "Unable to obtain local address" << std::endl;
1615       continue;
1616     }
1617 
1618     set_port(*local_addr, ep.addr);
1619 
1620     if (!config.quiet) {
1621       std::array<char, IF_NAMESIZE> ifname;
1622       std::cerr << "Received packet: local="
1623                 << util::straddr(&local_addr->su.sa, local_addr->len)
1624                 << " remote=" << util::straddr(&su.sa, msg.msg_namelen)
1625                 << " if=" << if_indextoname(local_addr->ifindex, ifname.data())
1626                 << " ecn=0x" << std::hex << pi.ecn << std::dec << " " << nread
1627                 << " bytes" << std::endl;
1628     }
1629 
1630     if (debug::packet_lost(config.rx_loss_prob)) {
1631       if (!config.quiet) {
1632         std::cerr << "** Simulated incoming packet loss **" << std::endl;
1633       }
1634       continue;
1635     }
1636 
1637     if (nread == 0) {
1638       continue;
1639     }
1640 
1641     uint32_t version;
1642     const uint8_t *dcid, *scid;
1643     size_t dcidlen, scidlen;
1644 
1645     switch (auto rv = ngtcp2_pkt_decode_version_cid(&version, &dcid, &dcidlen,
1646                                                     &scid, &scidlen, buf.data(),
1647                                                     nread, NGTCP2_SV_SCIDLEN);
1648             rv) {
1649     case 0:
1650       break;
1651     case NGTCP2_ERR_VERSION_NEGOTIATION:
1652       send_version_negotiation(version, scid, scidlen, dcid, dcidlen, ep,
1653                                *local_addr, &su.sa, msg.msg_namelen);
1654       continue;
1655     default:
1656       std::cerr << "Could not decode version and CID from QUIC packet header: "
1657                 << ngtcp2_strerror(rv) << std::endl;
1658       continue;
1659     }
1660 
1661     auto dcid_key = util::make_cid_key(dcid, dcidlen);
1662 
1663     auto handler_it = handlers_.find(dcid_key);
1664     if (handler_it == std::end(handlers_)) {
1665       switch (auto rv = ngtcp2_accept(&hd, buf.data(), nread); rv) {
1666       case 0:
1667         break;
1668       case NGTCP2_ERR_RETRY:
1669         send_retry(&hd, ep, *local_addr, &su.sa, msg.msg_namelen);
1670         continue;
1671       case NGTCP2_ERR_VERSION_NEGOTIATION:
1672         if (!config.quiet) {
1673           std::cerr << "Unsupported version: Send Version Negotiation"
1674                     << std::endl;
1675         }
1676         send_version_negotiation(hd.version, hd.scid.data, hd.scid.datalen,
1677                                  hd.dcid.data, hd.dcid.datalen, ep, *local_addr,
1678                                  &su.sa, msg.msg_namelen);
1679         continue;
1680       default:
1681         if (!config.quiet) {
1682           std::cerr << "Unexpected packet received: length=" << nread
1683                     << std::endl;
1684         }
1685         continue;
1686       }
1687 
1688       ngtcp2_cid ocid;
1689       ngtcp2_cid *pocid = nullptr;
1690 
1691       assert(hd.type == NGTCP2_PKT_INITIAL);
1692 
1693       if (config.validate_addr || hd.token.len) {
1694         std::cerr << "Perform stateless address validation" << std::endl;
1695         if (hd.token.len == 0) {
1696           send_retry(&hd, ep, *local_addr, &su.sa, msg.msg_namelen);
1697           continue;
1698         }
1699 
1700         if (hd.token.base[0] != NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY &&
1701             hd.dcid.datalen < NGTCP2_MIN_INITIAL_DCIDLEN) {
1702           send_stateless_connection_close(&hd, ep, *local_addr, &su.sa,
1703                                           msg.msg_namelen);
1704           continue;
1705         }
1706 
1707         switch (hd.token.base[0]) {
1708         case NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY:
1709           if (verify_retry_token(&ocid, &hd, &su.sa, msg.msg_namelen) != 0) {
1710             send_stateless_connection_close(&hd, ep, *local_addr, &su.sa,
1711                                             msg.msg_namelen);
1712             continue;
1713           }
1714           pocid = &ocid;
1715           break;
1716         case NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR:
1717           if (verify_token(&hd, &su.sa, msg.msg_namelen) != 0) {
1718             if (config.validate_addr) {
1719               send_retry(&hd, ep, *local_addr, &su.sa, msg.msg_namelen);
1720               continue;
1721             }
1722 
1723             hd.token.base = nullptr;
1724             hd.token.len = 0;
1725           }
1726           break;
1727         default:
1728           if (!config.quiet) {
1729             std::cerr << "Ignore unrecognized token" << std::endl;
1730           }
1731           if (config.validate_addr) {
1732             send_retry(&hd, ep, *local_addr, &su.sa, msg.msg_namelen);
1733             continue;
1734           }
1735 
1736           hd.token.base = nullptr;
1737           hd.token.len = 0;
1738           break;
1739         }
1740       }
1741 
1742       auto h = std::make_unique<Handler>(loop_, this);
1743       if (h->init(ep, *local_addr, &su.sa, msg.msg_namelen, &hd.scid, &hd.dcid,
1744                   pocid, hd.token.base, hd.token.len, hd.version,
1745                   tls_ctx_) != 0) {
1746         continue;
1747       }
1748 
1749       switch (h->on_read(ep, *local_addr, &su.sa, msg.msg_namelen, &pi,
1750                          buf.data(), nread)) {
1751       case 0:
1752         break;
1753       case NETWORK_ERR_RETRY:
1754         send_retry(&hd, ep, *local_addr, &su.sa, msg.msg_namelen);
1755         continue;
1756       default:
1757         continue;
1758       }
1759 
1760       switch (h->on_write()) {
1761       case 0:
1762         break;
1763       default:
1764         continue;
1765       }
1766 
1767       std::array<ngtcp2_cid, 2> scids;
1768       auto conn = h->conn();
1769 
1770       auto num_scid = ngtcp2_conn_get_num_scid(conn);
1771 
1772       assert(num_scid <= scids.size());
1773 
1774       ngtcp2_conn_get_scid(conn, scids.data());
1775 
1776       for (size_t i = 0; i < num_scid; ++i) {
1777         handlers_.emplace(util::make_cid_key(&scids[i]), h.get());
1778       }
1779 
1780       handlers_.emplace(dcid_key, h.get());
1781 
1782       h.release();
1783 
1784       continue;
1785     }
1786 
1787     auto h = (*handler_it).second;
1788     if (ngtcp2_conn_is_in_closing_period(h->conn())) {
1789       // TODO do exponential backoff.
1790       switch (h->send_conn_close()) {
1791       case 0:
1792         break;
1793       default:
1794         remove(h);
1795       }
1796       continue;
1797     }
1798     if (h->draining()) {
1799       continue;
1800     }
1801 
1802     if (auto rv = h->on_read(ep, *local_addr, &su.sa, msg.msg_namelen, &pi,
1803                              buf.data(), nread);
1804         rv != 0) {
1805       if (rv != NETWORK_ERR_CLOSE_WAIT) {
1806         remove(h);
1807       }
1808       continue;
1809     }
1810 
1811     h->signal_write();
1812   }
1813 
1814   return 0;
1815 }
1816 
1817 namespace {
generate_reserved_version(const sockaddr * sa,socklen_t salen,uint32_t version)1818 uint32_t generate_reserved_version(const sockaddr *sa, socklen_t salen,
1819                                    uint32_t version) {
1820   uint32_t h = 0x811C9DC5u;
1821   const uint8_t *p = (const uint8_t *)sa;
1822   const uint8_t *ep = p + salen;
1823   for (; p != ep; ++p) {
1824     h ^= *p;
1825     h *= 0x01000193u;
1826   }
1827   version = htonl(version);
1828   p = (const uint8_t *)&version;
1829   ep = p + sizeof(version);
1830   for (; p != ep; ++p) {
1831     h ^= *p;
1832     h *= 0x01000193u;
1833   }
1834   h &= 0xf0f0f0f0u;
1835   h |= 0x0a0a0a0au;
1836   return h;
1837 }
1838 } // namespace
1839 
send_version_negotiation(uint32_t version,const uint8_t * dcid,size_t dcidlen,const uint8_t * scid,size_t scidlen,Endpoint & ep,const Address & local_addr,const sockaddr * sa,socklen_t salen)1840 int Server::send_version_negotiation(uint32_t version, const uint8_t *dcid,
1841                                      size_t dcidlen, const uint8_t *scid,
1842                                      size_t scidlen, Endpoint &ep,
1843                                      const Address &local_addr,
1844                                      const sockaddr *sa, socklen_t salen) {
1845   Buffer buf{NGTCP2_MAX_UDP_PAYLOAD_SIZE};
1846   std::array<uint32_t, 16> sv;
1847 
1848   static_assert(sv.size() >= 2 + (NGTCP2_PROTO_VER_DRAFT_MAX -
1849                                   NGTCP2_PROTO_VER_DRAFT_MIN + 1));
1850 
1851   sv[0] = generate_reserved_version(sa, salen, version);
1852   sv[1] = NGTCP2_PROTO_VER_V1;
1853 
1854   size_t svlen = 2;
1855   for (auto v = NGTCP2_PROTO_VER_DRAFT_MIN; v <= NGTCP2_PROTO_VER_DRAFT_MAX;
1856        ++v) {
1857     sv[svlen++] = v;
1858   }
1859 
1860   auto nwrite = ngtcp2_pkt_write_version_negotiation(
1861       buf.wpos(), buf.left(),
1862       std::uniform_int_distribution<uint8_t>(
1863           0, std::numeric_limits<uint8_t>::max())(randgen),
1864       dcid, dcidlen, scid, scidlen, sv.data(), svlen);
1865   if (nwrite < 0) {
1866     std::cerr << "ngtcp2_pkt_write_version_negotiation: "
1867               << ngtcp2_strerror(nwrite) << std::endl;
1868     return -1;
1869   }
1870 
1871   buf.push(nwrite);
1872 
1873   ngtcp2_addr laddr{
1874       const_cast<sockaddr *>(&local_addr.su.sa),
1875       local_addr.len,
1876   };
1877   ngtcp2_addr raddr{
1878       const_cast<sockaddr *>(sa),
1879       salen,
1880   };
1881 
1882   if (send_packet(ep, laddr, raddr, /* ecn = */ 0, buf.rpos(), buf.size(), 0) !=
1883       NETWORK_ERR_OK) {
1884     return -1;
1885   }
1886 
1887   return 0;
1888 }
1889 
send_retry(const ngtcp2_pkt_hd * chd,Endpoint & ep,const Address & local_addr,const sockaddr * sa,socklen_t salen)1890 int Server::send_retry(const ngtcp2_pkt_hd *chd, Endpoint &ep,
1891                        const Address &local_addr, const sockaddr *sa,
1892                        socklen_t salen) {
1893   std::array<char, NI_MAXHOST> host;
1894   std::array<char, NI_MAXSERV> port;
1895 
1896   if (auto rv = getnameinfo(sa, salen, host.data(), host.size(), port.data(),
1897                             port.size(), NI_NUMERICHOST | NI_NUMERICSERV);
1898       rv != 0) {
1899     std::cerr << "getnameinfo: " << gai_strerror(rv) << std::endl;
1900     return -1;
1901   }
1902 
1903   if (!config.quiet) {
1904     std::cerr << "Sending Retry packet to [" << host.data()
1905               << "]:" << port.data() << std::endl;
1906   }
1907 
1908   ngtcp2_cid scid;
1909 
1910   scid.datalen = NGTCP2_SV_SCIDLEN;
1911   if (util::generate_secure_random(scid.data, scid.datalen) != 0) {
1912     return -1;
1913   }
1914 
1915   std::array<uint8_t, NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN> token;
1916 
1917   auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
1918                std::chrono::system_clock::now().time_since_epoch())
1919                .count();
1920 
1921   auto tokenlen = ngtcp2_crypto_generate_retry_token(
1922       token.data(), config.static_secret.data(), config.static_secret.size(),
1923       sa, salen, &scid, &chd->dcid, t);
1924   if (tokenlen < 0) {
1925     return -1;
1926   }
1927 
1928   if (!config.quiet) {
1929     std::cerr << "Generated address validation token:" << std::endl;
1930     util::hexdump(stderr, token.data(), tokenlen);
1931   }
1932 
1933   Buffer buf{NGTCP2_MAX_UDP_PAYLOAD_SIZE};
1934 
1935   auto nwrite = ngtcp2_crypto_write_retry(buf.wpos(), buf.left(), chd->version,
1936                                           &chd->scid, &scid, &chd->dcid,
1937                                           token.data(), tokenlen);
1938   if (nwrite < 0) {
1939     std::cerr << "ngtcp2_crypto_write_retry failed" << std::endl;
1940     return -1;
1941   }
1942 
1943   buf.push(nwrite);
1944 
1945   ngtcp2_addr laddr{
1946       const_cast<sockaddr *>(&local_addr.su.sa),
1947       local_addr.len,
1948   };
1949   ngtcp2_addr raddr{
1950       const_cast<sockaddr *>(sa),
1951       salen,
1952   };
1953 
1954   if (send_packet(ep, laddr, raddr, /* ecn = */ 0, buf.rpos(), buf.size(), 0) !=
1955       NETWORK_ERR_OK) {
1956     return -1;
1957   }
1958 
1959   return 0;
1960 }
1961 
send_stateless_connection_close(const ngtcp2_pkt_hd * chd,Endpoint & ep,const Address & local_addr,const sockaddr * sa,socklen_t salen)1962 int Server::send_stateless_connection_close(const ngtcp2_pkt_hd *chd,
1963                                             Endpoint &ep,
1964                                             const Address &local_addr,
1965                                             const sockaddr *sa,
1966                                             socklen_t salen) {
1967   Buffer buf{NGTCP2_MAX_UDP_PAYLOAD_SIZE};
1968 
1969   auto nwrite = ngtcp2_crypto_write_connection_close(
1970       buf.wpos(), buf.left(), chd->version, &chd->scid, &chd->dcid,
1971       NGTCP2_INVALID_TOKEN);
1972   if (nwrite < 0) {
1973     std::cerr << "ngtcp2_crypto_write_connection_close failed" << std::endl;
1974     return -1;
1975   }
1976 
1977   buf.push(nwrite);
1978 
1979   ngtcp2_addr laddr{
1980       const_cast<sockaddr *>(&local_addr.su.sa),
1981       local_addr.len,
1982   };
1983   ngtcp2_addr raddr{
1984       const_cast<sockaddr *>(sa),
1985       salen,
1986   };
1987 
1988   if (send_packet(ep, laddr, raddr, /* ecn = */ 0, buf.rpos(), buf.size(), 0) !=
1989       NETWORK_ERR_OK) {
1990     return -1;
1991   }
1992 
1993   return 0;
1994 }
1995 
verify_retry_token(ngtcp2_cid * ocid,const ngtcp2_pkt_hd * hd,const sockaddr * sa,socklen_t salen)1996 int Server::verify_retry_token(ngtcp2_cid *ocid, const ngtcp2_pkt_hd *hd,
1997                                const sockaddr *sa, socklen_t salen) {
1998   std::array<char, NI_MAXHOST> host;
1999   std::array<char, NI_MAXSERV> port;
2000 
2001   if (auto rv = getnameinfo(sa, salen, host.data(), host.size(), port.data(),
2002                             port.size(), NI_NUMERICHOST | NI_NUMERICSERV);
2003       rv != 0) {
2004     std::cerr << "getnameinfo: " << gai_strerror(rv) << std::endl;
2005     return -1;
2006   }
2007 
2008   if (!config.quiet) {
2009     std::cerr << "Verifying Retry token from [" << host.data()
2010               << "]:" << port.data() << std::endl;
2011     util::hexdump(stderr, hd->token.base, hd->token.len);
2012   }
2013 
2014   auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
2015                std::chrono::system_clock::now().time_since_epoch())
2016                .count();
2017 
2018   if (ngtcp2_crypto_verify_retry_token(
2019           ocid, hd->token.base, hd->token.len, config.static_secret.data(),
2020           config.static_secret.size(), sa, salen, &hd->dcid,
2021           10 * NGTCP2_SECONDS, t) != 0) {
2022     std::cerr << "Could not verify Retry token" << std::endl;
2023 
2024     return -1;
2025   }
2026 
2027   if (!config.quiet) {
2028     std::cerr << "Token was successfully validated" << std::endl;
2029   }
2030 
2031   return 0;
2032 }
2033 
verify_token(const ngtcp2_pkt_hd * hd,const sockaddr * sa,socklen_t salen)2034 int Server::verify_token(const ngtcp2_pkt_hd *hd, const sockaddr *sa,
2035                          socklen_t salen) {
2036   std::array<char, NI_MAXHOST> host;
2037   std::array<char, NI_MAXSERV> port;
2038 
2039   if (auto rv = getnameinfo(sa, salen, host.data(), host.size(), port.data(),
2040                             port.size(), NI_NUMERICHOST | NI_NUMERICSERV);
2041       rv != 0) {
2042     std::cerr << "getnameinfo: " << gai_strerror(rv) << std::endl;
2043     return -1;
2044   }
2045 
2046   if (!config.quiet) {
2047     std::cerr << "Verifying token from [" << host.data() << "]:" << port.data()
2048               << std::endl;
2049     util::hexdump(stderr, hd->token.base, hd->token.len);
2050   }
2051 
2052   auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
2053                std::chrono::system_clock::now().time_since_epoch())
2054                .count();
2055 
2056   if (ngtcp2_crypto_verify_regular_token(hd->token.base, hd->token.len,
2057                                          config.static_secret.data(),
2058                                          config.static_secret.size(), sa, salen,
2059                                          3600 * NGTCP2_SECONDS, t) != 0) {
2060     std::cerr << "Could not verify token" << std::endl;
2061 
2062     return -1;
2063   }
2064 
2065   if (!config.quiet) {
2066     std::cerr << "Token was successfully validated" << std::endl;
2067   }
2068 
2069   return 0;
2070 }
2071 
send_packet(Endpoint & ep,const ngtcp2_addr & local_addr,const ngtcp2_addr & remote_addr,unsigned int ecn,const uint8_t * data,size_t datalen,size_t gso_size)2072 int Server::send_packet(Endpoint &ep, const ngtcp2_addr &local_addr,
2073                         const ngtcp2_addr &remote_addr, unsigned int ecn,
2074                         const uint8_t *data, size_t datalen, size_t gso_size) {
2075   if (debug::packet_lost(config.tx_loss_prob)) {
2076     if (!config.quiet) {
2077       std::cerr << "** Simulated outgoing packet loss **" << std::endl;
2078     }
2079     return NETWORK_ERR_OK;
2080   }
2081 
2082   iovec msg_iov;
2083   msg_iov.iov_base = const_cast<uint8_t *>(data);
2084   msg_iov.iov_len = datalen;
2085 
2086   msghdr msg{};
2087   msg.msg_name = const_cast<sockaddr *>(remote_addr.addr);
2088   msg.msg_namelen = remote_addr.addrlen;
2089   msg.msg_iov = &msg_iov;
2090   msg.msg_iovlen = 1;
2091 
2092   uint8_t msg_ctrl[
2093 #if NGTCP2_ENABLE_UDP_GSO
2094       CMSG_SPACE(sizeof(uint16_t)) +
2095 #endif // NGTCP2_ENABLE_UDP_GSO
2096       CMSG_SPACE(sizeof(in6_pktinfo))];
2097 
2098   memset(msg_ctrl, 0, sizeof(msg_ctrl));
2099 
2100   msg.msg_control = msg_ctrl;
2101   msg.msg_controllen = sizeof(msg_ctrl);
2102 
2103   size_t controllen = 0;
2104 
2105   auto cm = CMSG_FIRSTHDR(&msg);
2106 
2107   switch (local_addr.addr->sa_family) {
2108   case AF_INET: {
2109     controllen += CMSG_SPACE(sizeof(in_pktinfo));
2110     cm->cmsg_level = IPPROTO_IP;
2111     cm->cmsg_type = IP_PKTINFO;
2112     cm->cmsg_len = CMSG_LEN(sizeof(in_pktinfo));
2113     auto pktinfo = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cm));
2114     memset(pktinfo, 0, sizeof(in_pktinfo));
2115     auto addrin = reinterpret_cast<sockaddr_in *>(local_addr.addr);
2116     pktinfo->ipi_spec_dst = addrin->sin_addr;
2117     break;
2118   }
2119   case AF_INET6: {
2120     controllen += CMSG_SPACE(sizeof(in6_pktinfo));
2121     cm->cmsg_level = IPPROTO_IPV6;
2122     cm->cmsg_type = IPV6_PKTINFO;
2123     cm->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
2124     auto pktinfo = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cm));
2125     memset(pktinfo, 0, sizeof(in6_pktinfo));
2126     auto addrin = reinterpret_cast<sockaddr_in6 *>(local_addr.addr);
2127     pktinfo->ipi6_addr = addrin->sin6_addr;
2128     break;
2129   }
2130   default:
2131     assert(0);
2132   }
2133 
2134 #if NGTCP2_ENABLE_UDP_GSO
2135   if (gso_size && datalen > gso_size) {
2136     controllen += CMSG_SPACE(sizeof(uint16_t));
2137     cm = CMSG_NXTHDR(&msg, cm);
2138     cm->cmsg_level = SOL_UDP;
2139     cm->cmsg_type = UDP_SEGMENT;
2140     cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
2141     *(reinterpret_cast<uint16_t *>(CMSG_DATA(cm))) = gso_size;
2142   }
2143 #endif // NGTCP2_ENABLE_UDP_GSO
2144 
2145   msg.msg_controllen = controllen;
2146 
2147   if (ep.ecn != ecn) {
2148     ep.ecn = ecn;
2149     fd_set_ecn(ep.fd, ep.addr.su.storage.ss_family, ecn);
2150   }
2151 
2152   ssize_t nwrite = 0;
2153 
2154   do {
2155     nwrite = sendmsg(ep.fd, &msg, 0);
2156   } while (nwrite == -1 && errno == EINTR);
2157 
2158   if (nwrite == -1) {
2159     std::cerr << "sendmsg: " << strerror(errno) << std::endl;
2160     // TODO We have packet which is expected to fail to send (e.g.,
2161     // path validation to old path).
2162     return NETWORK_ERR_OK;
2163   }
2164 
2165   if (!config.quiet) {
2166     std::cerr << "Sent packet: local="
2167               << util::straddr(local_addr.addr, local_addr.addrlen)
2168               << " remote="
2169               << util::straddr(remote_addr.addr, remote_addr.addrlen)
2170               << " ecn=0x" << std::hex << ecn << std::dec << " " << nwrite
2171               << " bytes" << std::endl;
2172   }
2173 
2174   return NETWORK_ERR_OK;
2175 }
2176 
associate_cid(const ngtcp2_cid * cid,Handler * h)2177 void Server::associate_cid(const ngtcp2_cid *cid, Handler *h) {
2178   handlers_.emplace(util::make_cid_key(cid), h);
2179 }
2180 
dissociate_cid(const ngtcp2_cid * cid)2181 void Server::dissociate_cid(const ngtcp2_cid *cid) {
2182   handlers_.erase(util::make_cid_key(cid));
2183 }
2184 
remove(const Handler * h)2185 void Server::remove(const Handler *h) {
2186   auto conn = h->conn();
2187 
2188   handlers_.erase(
2189       util::make_cid_key(ngtcp2_conn_get_client_initial_dcid(conn)));
2190 
2191   std::vector<ngtcp2_cid> cids(ngtcp2_conn_get_num_scid(conn));
2192   ngtcp2_conn_get_scid(conn, cids.data());
2193 
2194   for (auto &cid : cids) {
2195     handlers_.erase(util::make_cid_key(&cid));
2196   }
2197 
2198   delete h;
2199 }
2200 
2201 namespace {
parse_host_port(Address & dest,int af,const char * first,const char * last)2202 int parse_host_port(Address &dest, int af, const char *first,
2203                     const char *last) {
2204   if (std::distance(first, last) == 0) {
2205     return -1;
2206   }
2207 
2208   const char *host_begin, *host_end, *it;
2209   if (*first == '[') {
2210     host_begin = first + 1;
2211     it = std::find(host_begin, last, ']');
2212     if (it == last) {
2213       return -1;
2214     }
2215     host_end = it;
2216     ++it;
2217     if (it == last || *it != ':') {
2218       return -1;
2219     }
2220   } else {
2221     host_begin = first;
2222     it = std::find(host_begin, last, ':');
2223     if (it == last) {
2224       return -1;
2225     }
2226     host_end = it;
2227   }
2228 
2229   if (++it == last) {
2230     return -1;
2231   }
2232   auto svc_begin = it;
2233 
2234   std::array<char, NI_MAXHOST> host;
2235   *std::copy(host_begin, host_end, std::begin(host)) = '\0';
2236 
2237   addrinfo hints{}, *res;
2238   hints.ai_family = af;
2239   hints.ai_socktype = SOCK_DGRAM;
2240 
2241   if (auto rv = getaddrinfo(host.data(), svc_begin, &hints, &res); rv != 0) {
2242     std::cerr << "getaddrinfo: [" << host.data() << "]:" << svc_begin << ": "
2243               << gai_strerror(rv) << std::endl;
2244     return -1;
2245   }
2246 
2247   dest.len = res->ai_addrlen;
2248   memcpy(&dest.su, res->ai_addr, res->ai_addrlen);
2249 
2250   freeaddrinfo(res);
2251 
2252   return 0;
2253 }
2254 } // namespace
2255 
2256 namespace {
print_usage()2257 void print_usage() {
2258   std::cerr << "Usage: server [OPTIONS] <ADDR> <PORT> <PRIVATE_KEY_FILE> "
2259                "<CERTIFICATE_FILE>"
2260             << std::endl;
2261 }
2262 } // namespace
2263 
2264 namespace {
config_set_default(Config & config)2265 void config_set_default(Config &config) {
2266   config = Config{};
2267   config.tx_loss_prob = 0.;
2268   config.rx_loss_prob = 0.;
2269   config.ciphers = util::crypto_default_ciphers();
2270   config.groups = util::crypto_default_groups();
2271   config.timeout = 30 * NGTCP2_SECONDS;
2272   {
2273     auto path = realpath(".", nullptr);
2274     assert(path);
2275     config.htdocs = path;
2276     free(path);
2277   }
2278   config.mime_types_file = "/etc/mime.types";
2279   config.max_data = 1_m;
2280   config.max_stream_data_bidi_local = 256_k;
2281   config.max_stream_data_bidi_remote = 256_k;
2282   config.max_stream_data_uni = 256_k;
2283   config.max_streams_bidi = 100;
2284   config.max_streams_uni = 3;
2285   config.max_dyn_length = 20_m;
2286   config.cc_algo = NGTCP2_CC_ALGO_CUBIC;
2287   config.initial_rtt = NGTCP2_DEFAULT_INITIAL_RTT;
2288   config.max_gso_dgrams = 10;
2289 }
2290 } // namespace
2291 
2292 namespace {
print_help()2293 void print_help() {
2294   print_usage();
2295 
2296   config_set_default(config);
2297 
2298   std::cout << R"(
2299   <ADDR>      Address to listen to.  '*' binds to any address.
2300   <PORT>      Port
2301   <PRIVATE_KEY_FILE>
2302               Path to private key file
2303   <CERTIFICATE_FILE>
2304               Path to certificate file
2305 Options:
2306   -t, --tx-loss=<P>
2307               The probability of losing outgoing packets.  <P> must be
2308               [0.0, 1.0],  inclusive.  0.0 means no  packet loss.  1.0
2309               means 100% packet loss.
2310   -r, --rx-loss=<P>
2311               The probability of losing incoming packets.  <P> must be
2312               [0.0, 1.0],  inclusive.  0.0 means no  packet loss.  1.0
2313               means 100% packet loss.
2314   --ciphers=<CIPHERS>
2315               Specify the cipher suite list to enable.
2316               Default: )"
2317             << config.ciphers << R"(
2318   --groups=<GROUPS>
2319               Specify the supported groups.
2320               Default: )"
2321             << config.groups << R"(
2322   -d, --htdocs=<PATH>
2323               Specify document root.  If this option is not specified,
2324               the document root is the current working directory.
2325   -q, --quiet Suppress debug output.
2326   -s, --show-secret
2327               Print out secrets unless --quiet is used.
2328   --timeout=<DURATION>
2329               Specify idle timeout.
2330               Default: )"
2331             << util::format_duration(config.timeout) << R"(
2332   -V, --validate-addr
2333               Perform address validation.
2334   --preferred-ipv4-addr=<ADDR>:<PORT>
2335               Specify preferred IPv4 address and port.
2336   --preferred-ipv6-addr=<ADDR>:<PORT>
2337               Specify preferred IPv6 address and port.  A numeric IPv6
2338               address  must   be  enclosed  by  '['   and  ']'  (e.g.,
2339               [::1]:8443)
2340   --mime-types-file=<PATH>
2341               Path  to file  that contains  MIME media  types and  the
2342               extensions.
2343               Default: )"
2344             << config.mime_types_file << R"(
2345   --early-response
2346               Start  sending response  when  it  receives HTTP  header
2347               fields  without  waiting  for  request  body.   If  HTTP
2348               response data is written  before receiving request body,
2349               STOP_SENDING is sent.
2350   --verify-client
2351               Request a  client certificate.   At the moment,  we just
2352               request a certificate and no verification is done.
2353   --qlog-dir=<PATH>
2354               Path to  the directory where  qlog file is  stored.  The
2355               file name  of each qlog  is the Source Connection  ID of
2356               server.
2357   --no-quic-dump
2358               Disables printing QUIC STREAM and CRYPTO frame data out.
2359   --no-http-dump
2360               Disables printing HTTP response body out.
2361   --max-data=<SIZE>
2362               The initial connection-level flow control window.
2363               Default: )"
2364             << util::format_uint_iec(config.max_data) << R"(
2365   --max-stream-data-bidi-local=<SIZE>
2366               The  initial  stream-level  flow control  window  for  a
2367               bidirectional stream that the local endpoint initiates.
2368               Default: )"
2369             << util::format_uint_iec(config.max_stream_data_bidi_local) << R"(
2370   --max-stream-data-bidi-remote=<SIZE>
2371               The  initial  stream-level  flow control  window  for  a
2372               bidirectional stream that the remote endpoint initiates.
2373               Default: )"
2374             << util::format_uint_iec(config.max_stream_data_bidi_remote) << R"(
2375   --max-stream-data-uni=<SIZE>
2376               The  initial  stream-level  flow control  window  for  a
2377               unidirectional stream.
2378               Default: )"
2379             << util::format_uint_iec(config.max_stream_data_uni) << R"(
2380   --max-streams-bidi=<N>
2381               The number of the concurrent bidirectional streams.
2382               Default: )"
2383             << config.max_streams_bidi << R"(
2384   --max-streams-uni=<N>
2385               The number of the concurrent unidirectional streams.
2386               Default: )"
2387             << config.max_streams_uni << R"(
2388   --max-dyn-length=<SIZE>
2389               The maximum length of a dynamically generated content.
2390               Default: )"
2391             << util::format_uint_iec(config.max_dyn_length) << R"(
2392   --cc=(cubic|reno|bbr)
2393               The name of congestion controller algorithm.
2394               Default: )"
2395             << util::strccalgo(config.cc_algo) << R"(
2396   --initial-rtt=<DURATION>
2397               Set an initial RTT.
2398               Default: )"
2399             << util::format_duration(config.initial_rtt) << R"(
2400   --max-udp-payload-size=<SIZE>
2401               Override maximum UDP payload size that server transmits.
2402   --send-trailers
2403               Send trailer fields.
2404   --max-gso-dgrams=<N>
2405               Maximum  number of  UDP  datagrams that  are  sent in  a
2406               single GSO sendmsg call.
2407               Default: )"
2408             << config.max_gso_dgrams << R"(
2409   -h, --help  Display this help and exit.
2410 
2411 ---
2412 
2413   The <SIZE> argument is an integer and an optional unit (e.g., 10K is
2414   10 * 1024).  Units are K, M and G (powers of 1024).
2415 
2416   The <DURATION> argument is an integer and an optional unit (e.g., 1s
2417   is 1 second and 500ms is 500  milliseconds).  Units are h, m, s, ms,
2418   us, or ns (hours,  minutes, seconds, milliseconds, microseconds, and
2419   nanoseconds respectively).  If  a unit is omitted, a  second is used
2420   as unit.)" << std::endl;
2421 }
2422 } // namespace
2423 
2424 std::ofstream keylog_file;
2425 
main(int argc,char ** argv)2426 int main(int argc, char **argv) {
2427   config_set_default(config);
2428 
2429   for (;;) {
2430     static int flag = 0;
2431     constexpr static option long_opts[] = {
2432         {"help", no_argument, nullptr, 'h'},
2433         {"tx-loss", required_argument, nullptr, 't'},
2434         {"rx-loss", required_argument, nullptr, 'r'},
2435         {"htdocs", required_argument, nullptr, 'd'},
2436         {"quiet", no_argument, nullptr, 'q'},
2437         {"show-secret", no_argument, nullptr, 's'},
2438         {"validate-addr", no_argument, nullptr, 'V'},
2439         {"ciphers", required_argument, &flag, 1},
2440         {"groups", required_argument, &flag, 2},
2441         {"timeout", required_argument, &flag, 3},
2442         {"preferred-ipv4-addr", required_argument, &flag, 4},
2443         {"preferred-ipv6-addr", required_argument, &flag, 5},
2444         {"mime-types-file", required_argument, &flag, 6},
2445         {"early-response", no_argument, &flag, 7},
2446         {"verify-client", no_argument, &flag, 8},
2447         {"qlog-dir", required_argument, &flag, 9},
2448         {"no-quic-dump", no_argument, &flag, 10},
2449         {"no-http-dump", no_argument, &flag, 11},
2450         {"max-data", required_argument, &flag, 12},
2451         {"max-stream-data-bidi-local", required_argument, &flag, 13},
2452         {"max-stream-data-bidi-remote", required_argument, &flag, 14},
2453         {"max-stream-data-uni", required_argument, &flag, 15},
2454         {"max-streams-bidi", required_argument, &flag, 16},
2455         {"max-streams-uni", required_argument, &flag, 17},
2456         {"max-dyn-length", required_argument, &flag, 18},
2457         {"cc", required_argument, &flag, 19},
2458         {"initial-rtt", required_argument, &flag, 20},
2459         {"max-udp-payload-size", required_argument, &flag, 21},
2460         {"send-trailers", no_argument, &flag, 22},
2461         {"max-gso-dgrams", required_argument, &flag, 25},
2462         {nullptr, 0, nullptr, 0}};
2463 
2464     auto optidx = 0;
2465     auto c = getopt_long(argc, argv, "d:hqr:st:V", long_opts, &optidx);
2466     if (c == -1) {
2467       break;
2468     }
2469     switch (c) {
2470     case 'd': {
2471       // --htdocs
2472       auto path = realpath(optarg, nullptr);
2473       if (path == nullptr) {
2474         std::cerr << "path: invalid path " << std::quoted(optarg) << std::endl;
2475         exit(EXIT_FAILURE);
2476       }
2477       config.htdocs = path;
2478       free(path);
2479       break;
2480     }
2481     case 'h':
2482       // --help
2483       print_help();
2484       exit(EXIT_SUCCESS);
2485     case 'q':
2486       // --quiet
2487       config.quiet = true;
2488       break;
2489     case 'r':
2490       // --rx-loss
2491       config.rx_loss_prob = strtod(optarg, nullptr);
2492       break;
2493     case 's':
2494       // --show-secret
2495       config.show_secret = true;
2496       break;
2497     case 't':
2498       // --tx-loss
2499       config.tx_loss_prob = strtod(optarg, nullptr);
2500       break;
2501     case 'V':
2502       // --validate-addr
2503       config.validate_addr = true;
2504       break;
2505     case '?':
2506       print_usage();
2507       exit(EXIT_FAILURE);
2508     case 0:
2509       switch (flag) {
2510       case 1:
2511         // --ciphers
2512         config.ciphers = optarg;
2513         break;
2514       case 2:
2515         // --groups
2516         config.groups = optarg;
2517         break;
2518       case 3:
2519         // --timeout
2520         if (auto t = util::parse_duration(optarg); !t) {
2521           std::cerr << "timeout: invalid argument" << std::endl;
2522           exit(EXIT_FAILURE);
2523         } else {
2524           config.timeout = *t;
2525         }
2526         break;
2527       case 4:
2528         // --preferred-ipv4-addr
2529         if (parse_host_port(config.preferred_ipv4_addr, AF_INET, optarg,
2530                             optarg + strlen(optarg)) != 0) {
2531           std::cerr << "preferred-ipv4-addr: could not use "
2532                     << std::quoted(optarg) << std::endl;
2533           exit(EXIT_FAILURE);
2534         }
2535         break;
2536       case 5:
2537         // --preferred-ipv6-addr
2538         if (parse_host_port(config.preferred_ipv6_addr, AF_INET6, optarg,
2539                             optarg + strlen(optarg)) != 0) {
2540           std::cerr << "preferred-ipv6-addr: could not use "
2541                     << std::quoted(optarg) << std::endl;
2542           exit(EXIT_FAILURE);
2543         }
2544         break;
2545       case 6:
2546         // --mime-types-file
2547         config.mime_types_file = optarg;
2548         break;
2549       case 7:
2550         // --early-response
2551         config.early_response = true;
2552         break;
2553       case 8:
2554         // --verify-client
2555         config.verify_client = true;
2556         break;
2557       case 9:
2558         // --qlog-dir
2559         config.qlog_dir = optarg;
2560         break;
2561       case 10:
2562         // --no-quic-dump
2563         config.no_quic_dump = true;
2564         break;
2565       case 11:
2566         // --no-http-dump
2567         config.no_http_dump = true;
2568         break;
2569       case 12:
2570         // --max-data
2571         if (auto n = util::parse_uint_iec(optarg); !n) {
2572           std::cerr << "max-data: invalid argument" << std::endl;
2573           exit(EXIT_FAILURE);
2574         } else {
2575           config.max_data = *n;
2576         }
2577         break;
2578       case 13:
2579         // --max-stream-data-bidi-local
2580         if (auto n = util::parse_uint_iec(optarg); !n) {
2581           std::cerr << "max-stream-data-bidi-local: invalid argument"
2582                     << std::endl;
2583           exit(EXIT_FAILURE);
2584         } else {
2585           config.max_stream_data_bidi_local = *n;
2586         }
2587         break;
2588       case 14:
2589         // --max-stream-data-bidi-remote
2590         if (auto n = util::parse_uint_iec(optarg); !n) {
2591           std::cerr << "max-stream-data-bidi-remote: invalid argument"
2592                     << std::endl;
2593           exit(EXIT_FAILURE);
2594         } else {
2595           config.max_stream_data_bidi_remote = *n;
2596         }
2597         break;
2598       case 15:
2599         // --max-stream-data-uni
2600         if (auto n = util::parse_uint_iec(optarg); !n) {
2601           std::cerr << "max-stream-data-uni: invalid argument" << std::endl;
2602           exit(EXIT_FAILURE);
2603         } else {
2604           config.max_stream_data_uni = *n;
2605         }
2606         break;
2607       case 16:
2608         // --max-streams-bidi
2609         if (auto n = util::parse_uint(optarg); !n) {
2610           std::cerr << "max-streams-bidi: invalid argument" << std::endl;
2611           exit(EXIT_FAILURE);
2612         } else {
2613           config.max_streams_bidi = *n;
2614         }
2615         break;
2616       case 17:
2617         // --max-streams-uni
2618         if (auto n = util::parse_uint(optarg); !n) {
2619           std::cerr << "max-streams-uni: invalid argument" << std::endl;
2620           exit(EXIT_FAILURE);
2621         } else {
2622           config.max_streams_uni = *n;
2623         }
2624         break;
2625       case 18:
2626         // --max-dyn-length
2627         if (auto n = util::parse_uint_iec(optarg); !n) {
2628           std::cerr << "max-dyn-length: invalid argument" << std::endl;
2629           exit(EXIT_FAILURE);
2630         } else {
2631           config.max_dyn_length = *n;
2632         }
2633         break;
2634       case 19:
2635         // --cc
2636         if (strcmp("cubic", optarg) == 0) {
2637           config.cc_algo = NGTCP2_CC_ALGO_CUBIC;
2638           break;
2639         }
2640         if (strcmp("reno", optarg) == 0) {
2641           config.cc_algo = NGTCP2_CC_ALGO_RENO;
2642           break;
2643         }
2644         if (strcmp("bbr", optarg) == 0) {
2645           config.cc_algo = NGTCP2_CC_ALGO_BBR;
2646           break;
2647         }
2648         std::cerr << "cc: specify cubic, reno, or bbr" << std::endl;
2649         exit(EXIT_FAILURE);
2650       case 20:
2651         // --initial-rtt
2652         if (auto t = util::parse_duration(optarg); !t) {
2653           std::cerr << "initial-rtt: invalid argument" << std::endl;
2654           exit(EXIT_FAILURE);
2655         } else {
2656           config.initial_rtt = *t;
2657         }
2658         break;
2659       case 21:
2660         // --max-udp-payload-size
2661         if (auto n = util::parse_uint_iec(optarg); !n) {
2662           std::cerr << "max-udp-payload-size: invalid argument" << std::endl;
2663           exit(EXIT_FAILURE);
2664         } else if (*n > 64_k) {
2665           std::cerr << "max-udp-payload-size: must not exceed 65536"
2666                     << std::endl;
2667           exit(EXIT_FAILURE);
2668         } else {
2669           config.max_udp_payload_size = *n;
2670         }
2671         break;
2672       case 22:
2673         // --send-trailers
2674         config.send_trailers = true;
2675         break;
2676       case 25:
2677         // --max-gso-dgrams
2678         if (auto n = util::parse_uint(optarg); !n) {
2679           std::cerr << "max-gso-dgrams: invalid argument" << std::endl;
2680           exit(EXIT_FAILURE);
2681         } else {
2682           config.max_gso_dgrams = *n;
2683         }
2684         break;
2685       }
2686       break;
2687     default:
2688       break;
2689     };
2690   }
2691 
2692   if (argc - optind < 4) {
2693     std::cerr << "Too few arguments" << std::endl;
2694     print_usage();
2695     exit(EXIT_FAILURE);
2696   }
2697 
2698   auto addr = argv[optind++];
2699   auto port = argv[optind++];
2700   auto private_key_file = argv[optind++];
2701   auto cert_file = argv[optind++];
2702 
2703   if (auto n = util::parse_uint(port); !n) {
2704     std::cerr << "port: invalid port number" << std::endl;
2705     exit(EXIT_FAILURE);
2706   } else if (*n > 65535) {
2707     std::cerr << "port: must not exceed 65535" << std::endl;
2708     exit(EXIT_FAILURE);
2709   } else {
2710     config.port = *n;
2711   }
2712 
2713   if (auto mt = util::read_mime_types(config.mime_types_file); !mt) {
2714     std::cerr << "mime-types-file: Could not read MIME media types file "
2715               << std::quoted(config.mime_types_file) << std::endl;
2716   } else {
2717     config.mime_types = std::move(*mt);
2718   }
2719 
2720   TLSServerContext tls_ctx;
2721 
2722   if (tls_ctx.init(private_key_file, cert_file, AppProtocol::HQ) != 0) {
2723     exit(EXIT_FAILURE);
2724   }
2725 
2726   if (config.htdocs.back() != '/') {
2727     config.htdocs += '/';
2728   }
2729 
2730   std::cerr << "Using document root " << config.htdocs << std::endl;
2731 
2732   auto ev_loop_d = defer(ev_loop_destroy, EV_DEFAULT);
2733 
2734   auto keylog_filename = getenv("SSLKEYLOGFILE");
2735   if (keylog_filename) {
2736     keylog_file.open(keylog_filename, std::ios_base::app);
2737     if (keylog_file) {
2738       tls_ctx.enable_keylog();
2739     }
2740   }
2741 
2742   if (util::generate_secret(config.static_secret.data(),
2743                             config.static_secret.size()) != 0) {
2744     std::cerr << "Unable to generate static secret" << std::endl;
2745     exit(EXIT_FAILURE);
2746   }
2747 
2748   Server s(EV_DEFAULT, tls_ctx);
2749   if (s.init(addr, port) != 0) {
2750     exit(EXIT_FAILURE);
2751   }
2752 
2753   ev_run(EV_DEFAULT, 0);
2754 
2755   s.disconnect();
2756   s.close();
2757 
2758   return EXIT_SUCCESS;
2759 }
2760