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