|
31 | 31 | #include <memory> |
32 | 32 | #include <fstream> |
33 | 33 | #include <iomanip> |
| 34 | +#include <limits> |
| 35 | +#include <utility> |
34 | 36 |
|
35 | 37 | #include <unistd.h> |
36 | 38 | #include <getopt.h> |
@@ -216,6 +218,11 @@ Stream::open_file(const std::filesystem::path &path) { |
216 | 218 | close(fd); |
217 | 219 | } else { |
218 | 220 | fe.fd = fd; |
| 221 | + // A file larger than the address space cannot be mapped. |
| 222 | + if (std::cmp_greater(st.st_size, std::numeric_limits<size_t>::max())) { |
| 223 | + close(fd); |
| 224 | + return std::unexpected{Error::INTEGER_OVERFLOW}; |
| 225 | + } |
219 | 226 | fe.len = static_cast<size_t>(st.st_size); |
220 | 227 | if (fe.len) { |
221 | 228 | fe.map = mmap(nullptr, fe.len, PROT_READ, MAP_SHARED, fd, 0); |
@@ -321,9 +328,7 @@ void timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) { |
321 | 328 | } |
322 | 329 |
|
323 | 330 | if (auto rv = h->handle_expiry(); !rv) { |
324 | | - if (rv.error() == Error::CLOSE_WAIT) { |
325 | | - ev_timer_stop(loop, w); |
326 | | - } else { |
| 331 | + if (rv.error() != Error::CLOSE_WAIT) { |
327 | 332 | s->remove(h); |
328 | 333 | } |
329 | 334 |
|
@@ -773,6 +778,7 @@ Handler::init(const Endpoint &ep, const Address &local_addr, |
773 | 778 | settings.handshake_timeout = config.handshake_timeout; |
774 | 779 | settings.no_pmtud = config.no_pmtud; |
775 | 780 | settings.ack_thresh = config.ack_thresh; |
| 781 | + settings.write_stream_data_thresh = config.write_stream_data_thresh; |
776 | 782 | if (config.max_udp_payload_size) { |
777 | 783 | settings.max_tx_udp_payload_size = config.max_udp_payload_size; |
778 | 784 | settings.no_tx_udp_payload_size_shaping = 1; |
@@ -1705,7 +1711,9 @@ void Server::on_read(const Endpoint &ep) { |
1705 | 1711 | stderr, |
1706 | 1712 | "Received packet: local={} remote={} if={} ecn={:#x} {} bytes", |
1707 | 1713 | util::straddr(*local_addr), util::straddr(remote_addr), |
1708 | | - if_indextoname(local_addr->ifindex, ifname.data()), pi.ecn, datalen); |
| 1714 | + if_indextoname(local_addr->ifindex, ifname.data()) ? ifname.data() |
| 1715 | + : "(unknown)", |
| 1716 | + pi.ecn, datalen); |
1709 | 1717 | } |
1710 | 1718 |
|
1711 | 1719 | // Packets less than 21 bytes never be a valid QUIC packet. |
@@ -1735,6 +1743,11 @@ void Server::read_pkt(const Endpoint &ep, const Address &local_addr, |
1735 | 1743 | NGTCP2_SV_SCIDLEN); |
1736 | 1744 | rv) { |
1737 | 1745 | case 0: |
| 1746 | + if ((data[0] & 0x80U) && vc.version == 0) { |
| 1747 | + // Version Negotiation packet was received. |
| 1748 | + return; |
| 1749 | + } |
| 1750 | + |
1738 | 1751 | break; |
1739 | 1752 | case NGTCP2_ERR_VERSION_NEGOTIATION: |
1740 | 1753 | (void)send_version_negotiation(vc.version, {vc.scid, vc.scidlen}, |
@@ -2658,6 +2671,15 @@ void print_help() { |
2658 | 2671 | to send per an event loop in a single connection. It |
2659 | 2672 | defaults to 0, which means it is not limited by the |
2660 | 2673 | configuration. |
| 2674 | + --write-stream-data-thresh=<SIZE> |
| 2675 | + The threshold for the length of STREAM frame payload |
| 2676 | + that the local endpoint sends. If there is data more |
| 2677 | + than this value to send, and the flow control does not |
| 2678 | + allow sending more than this length, the data is not |
| 2679 | + sent, waiting for the window update from the remote |
| 2680 | + endpoint. |
| 2681 | + Default: )" |
| 2682 | + << config.write_stream_data_thresh << R"( |
2661 | 2683 | -h, --help Display this help and exit. |
2662 | 2684 |
|
2663 | 2685 | --- |
@@ -2732,6 +2754,7 @@ int main(int argc, char **argv) { |
2732 | 2754 | {"no-gso", no_argument, &flag, 35}, |
2733 | 2755 | {"show-stat", no_argument, &flag, 36}, |
2734 | 2756 | {"gso-burst", required_argument, &flag, 37}, |
| 2757 | + {"write-stream-data-thresh", required_argument, &flag, 38}, |
2735 | 2758 | {}, |
2736 | 2759 | }; |
2737 | 2760 |
|
@@ -3163,6 +3186,25 @@ int main(int argc, char **argv) { |
3163 | 3186 |
|
3164 | 3187 | break; |
3165 | 3188 | } |
| 3189 | + case 38: { |
| 3190 | + // --write-stream-data-thresh |
| 3191 | + auto n = util::parse_uint_iec(optarg); |
| 3192 | + if (!n) { |
| 3193 | + std::println(stderr, "write-stream-data-thresh: invalid argument"); |
| 3194 | + exit(EXIT_FAILURE); |
| 3195 | + } |
| 3196 | + |
| 3197 | + if (auto max = std::numeric_limits<size_t>::max(); *n > max) { |
| 3198 | + std::println( |
| 3199 | + stderr, |
| 3200 | + "write-stream-data-thresh: must be less than or equal to {}", max); |
| 3201 | + exit(EXIT_FAILURE); |
| 3202 | + } |
| 3203 | + |
| 3204 | + config.write_stream_data_thresh = static_cast<size_t>(*n); |
| 3205 | + |
| 3206 | + break; |
| 3207 | + } |
3166 | 3208 | } |
3167 | 3209 | break; |
3168 | 3210 | default: |
|
0 commit comments