Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7781:fdda518d10ba quic
Proper handling of packet number in header.
- fixed setting of largest received packet number.
- sending properly truncated packet number
- added support for multi-byte packet number
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Fri, 03 Apr 2020 14:02:16 +0300 |
parents | de8981bf2dd5 |
children | 0dc0552335bd |
comparison
equal
deleted
inserted
replaced
7780:de8981bf2dd5 | 7781:fdda518d10ba |
---|---|
46 typedef struct { | 46 typedef struct { |
47 ngx_quic_secret_t client_secret; | 47 ngx_quic_secret_t client_secret; |
48 ngx_quic_secret_t server_secret; | 48 ngx_quic_secret_t server_secret; |
49 | 49 |
50 uint64_t pnum; | 50 uint64_t pnum; |
51 uint64_t largest; | 51 uint64_t largest; /* number received from peer */ |
52 | 52 |
53 ngx_queue_t frames; | 53 ngx_queue_t frames; |
54 ngx_queue_t sent; | 54 ngx_queue_t sent; |
55 } ngx_quic_namespace_t; | 55 } ngx_quic_namespace_t; |
56 | 56 |
148 static ngx_int_t ngx_quic_output(ngx_connection_t *c); | 148 static ngx_int_t ngx_quic_output(ngx_connection_t *c); |
149 static ngx_int_t ngx_quic_output_ns(ngx_connection_t *c, | 149 static ngx_int_t ngx_quic_output_ns(ngx_connection_t *c, |
150 ngx_quic_namespace_t *ns, ngx_uint_t nsi); | 150 ngx_quic_namespace_t *ns, ngx_uint_t nsi); |
151 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames); | 151 static void ngx_quic_free_frames(ngx_connection_t *c, ngx_queue_t *frames); |
152 static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames); | 152 static ngx_int_t ngx_quic_send_frames(ngx_connection_t *c, ngx_queue_t *frames); |
153 | |
154 static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt, | |
155 ngx_quic_namespace_t *ns); | |
153 static void ngx_quic_retransmit_handler(ngx_event_t *ev); | 156 static void ngx_quic_retransmit_handler(ngx_event_t *ev); |
154 static ngx_int_t ngx_quic_retransmit_ns(ngx_connection_t *c, | 157 static ngx_int_t ngx_quic_retransmit_ns(ngx_connection_t *c, |
155 ngx_quic_namespace_t *ns, ngx_msec_t *waitp); | 158 ngx_quic_namespace_t *ns, ngx_msec_t *waitp); |
156 static void ngx_quic_push_handler(ngx_event_t *ev); | 159 static void ngx_quic_push_handler(ngx_event_t *ev); |
157 | 160 |
1233 | 1236 |
1234 if (!found) { | 1237 if (!found) { |
1235 | 1238 |
1236 if (ack->largest <= ns->pnum) { | 1239 if (ack->largest <= ns->pnum) { |
1237 /* duplicate ACK or ACK for non-ack-eliciting frame */ | 1240 /* duplicate ACK or ACK for non-ack-eliciting frame */ |
1238 return NGX_OK; | 1241 goto done; |
1239 } | 1242 } |
1240 | 1243 |
1241 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 1244 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
1242 "ACK for the packet not in sent queue "); | 1245 "ACK for the packet not in sent queue "); |
1243 // TODO: handle error properly: PROTOCOL VIOLATION? | 1246 // TODO: handle error properly: PROTOCOL VIOLATION? |
1244 return NGX_ERROR; | 1247 return NGX_ERROR; |
1245 } | 1248 } |
1246 | 1249 |
1250 done: | |
1251 | |
1247 /* 13.2.3. Receiver Tracking of ACK Frames */ | 1252 /* 13.2.3. Receiver Tracking of ACK Frames */ |
1248 if (ns->largest < ack->largest) { | 1253 if (ns->largest < ack->largest) { |
1249 ack->largest = ns->largest; | 1254 ns->largest = ack->largest; |
1255 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1256 "updated largest received: %ui", ns->largest); | |
1250 } | 1257 } |
1251 | 1258 |
1252 return NGX_OK; | 1259 return NGX_OK; |
1253 } | 1260 } |
1254 | 1261 |
1738 qc = c->quic; | 1745 qc = c->quic; |
1739 | 1746 |
1740 keys = &c->quic->keys[start->level]; | 1747 keys = &c->quic->keys[start->level]; |
1741 | 1748 |
1742 pkt.secret = &keys->server; | 1749 pkt.secret = &keys->server; |
1743 pkt.number = ns->pnum; | |
1744 | 1750 |
1745 if (start->level == ssl_encryption_initial) { | 1751 if (start->level == ssl_encryption_initial) { |
1746 pkt.flags = NGX_QUIC_PKT_INITIAL; | 1752 pkt.flags = NGX_QUIC_PKT_INITIAL; |
1747 pkt.token = initial_token; | 1753 pkt.token = initial_token; |
1748 | 1754 |
1749 } else if (start->level == ssl_encryption_handshake) { | 1755 } else if (start->level == ssl_encryption_handshake) { |
1750 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; | 1756 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; |
1751 } | 1757 |
1758 } else { | |
1759 pkt.flags = 0x40; // TODO: macro, set FIXED bit | |
1760 } | |
1761 | |
1762 ngx_quic_set_packet_number(&pkt, ns); | |
1752 | 1763 |
1753 pkt.log = c->log; | 1764 pkt.log = c->log; |
1754 pkt.level = start->level; | 1765 pkt.level = start->level; |
1755 pkt.dcid = qc->dcid; | 1766 pkt.dcid = qc->dcid; |
1756 pkt.scid = qc->scid; | 1767 pkt.scid = qc->scid; |
1774 | 1785 |
1775 now = ngx_current_msec; | 1786 now = ngx_current_msec; |
1776 start->last = now; | 1787 start->last = now; |
1777 | 1788 |
1778 return pkt.need_ack ? NGX_OK : NGX_DONE; | 1789 return pkt.need_ack ? NGX_OK : NGX_DONE; |
1790 } | |
1791 | |
1792 | |
1793 static void | |
1794 ngx_quic_set_packet_number(ngx_quic_header_t *pkt, ngx_quic_namespace_t *ns) | |
1795 { | |
1796 uint64_t delta; | |
1797 | |
1798 delta = ns->pnum - ns->largest; | |
1799 pkt->number = ns->pnum; | |
1800 | |
1801 if (delta <= 0x7F) { | |
1802 pkt->num_len = 1; | |
1803 pkt->trunc = ns->pnum & 0xff; | |
1804 | |
1805 } else if (delta <= 0x7FFF) { | |
1806 pkt->num_len = 2; | |
1807 pkt->flags |= 0x1; | |
1808 pkt->trunc = ns->pnum & 0xffff; | |
1809 | |
1810 } else if (delta <= 0x7FFFFF) { | |
1811 pkt->num_len = 3; | |
1812 pkt->flags |= 0x2; | |
1813 pkt->trunc = ns->pnum & 0xffffff; | |
1814 | |
1815 } else { | |
1816 pkt->num_len = 4; | |
1817 pkt->flags |= 0x3; | |
1818 pkt->trunc = ns->pnum & 0xffffffff; | |
1819 } | |
1779 } | 1820 } |
1780 | 1821 |
1781 | 1822 |
1782 static void | 1823 static void |
1783 ngx_quic_retransmit_handler(ngx_event_t *ev) | 1824 ngx_quic_retransmit_handler(ngx_event_t *ev) |