comparison src/event/ngx_event_quic.c @ 7854:2a94aaa70b33 quic

Cleaned up firefox workaround. The idea is to skip any zeroes that follow valid QUIC packet. Currently such behavior can be only observed with Firefox which sends zero-padded initial packets.
author Vladimir Homutov <vl@nginx.com>
date Thu, 07 May 2020 12:34:04 +0300
parents 9d9531431c8c
children 81a4f98a2556
comparison
equal deleted inserted replaced
7853:2d0f4aa78ed6 7854:2a94aaa70b33
161 static void ngx_quic_close_timer_handler(ngx_event_t *ev); 161 static void ngx_quic_close_timer_handler(ngx_event_t *ev);
162 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c, 162 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c,
163 ngx_quic_connection_t *qc); 163 ngx_quic_connection_t *qc);
164 164
165 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); 165 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b);
166 static ngx_inline u_char *ngx_quic_skip_zero_padding(ngx_buf_t *b);
166 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, 167 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c,
167 ngx_quic_header_t *pkt); 168 ngx_quic_header_t *pkt);
168 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c, 169 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c,
169 ngx_quic_header_t *pkt); 170 ngx_quic_header_t *pkt);
170 static ngx_int_t ngx_quic_early_input(ngx_connection_t *c, 171 static ngx_int_t ngx_quic_early_input(ngx_connection_t *c,
662 } 663 }
663 664
664 /* pos is at header end, adjust by actual packet length */ 665 /* pos is at header end, adjust by actual packet length */
665 pkt->raw->pos += pkt->len; 666 pkt->raw->pos += pkt->len;
666 667
668 (void) ngx_quic_skip_zero_padding(pkt->raw);
669
667 return ngx_quic_input(c, pkt->raw); 670 return ngx_quic_input(c, pkt->raw);
668 } 671 }
669 672
670 673
671 static ngx_int_t 674 static ngx_int_t
1054 pkt.raw = b; 1057 pkt.raw = b;
1055 pkt.data = p; 1058 pkt.data = p;
1056 pkt.len = b->last - p; 1059 pkt.len = b->last - p;
1057 pkt.log = c->log; 1060 pkt.log = c->log;
1058 pkt.flags = p[0]; 1061 pkt.flags = p[0];
1059
1060 if (pkt.flags == 0) {
1061 /* XXX: no idea WTF is this, just ignore */
1062 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
1063 "quic packet with zero flags, presumably"
1064 " firefox padding, ignored");
1065 break;
1066 }
1067 1062
1068 /* TODO: check current state */ 1063 /* TODO: check current state */
1069 if (ngx_quic_long_pkt(pkt.flags)) { 1064 if (ngx_quic_long_pkt(pkt.flags)) {
1070 1065
1071 if (ngx_quic_pkt_in(pkt.flags)) { 1066 if (ngx_quic_pkt_in(pkt.flags)) {
1106 * discard or buffer the packet for later processing and MUST 1101 * discard or buffer the packet for later processing and MUST
1107 * attempt to process the remaining packets. 1102 * attempt to process the remaining packets.
1108 */ 1103 */
1109 1104
1110 /* b->pos is at header end, adjust by actual packet length */ 1105 /* b->pos is at header end, adjust by actual packet length */
1111 p = b->pos + pkt.len; 1106 b->pos += pkt.len;
1112 b->pos = p; /* reset b->pos to the next packet start */ 1107 p = ngx_quic_skip_zero_padding(b);
1113 } 1108 }
1114 1109
1115 return NGX_OK; 1110 return NGX_OK;
1111 }
1112
1113
1114 /* firefox workaround: skip zero padding at the end of quic packet */
1115 static ngx_inline u_char *
1116 ngx_quic_skip_zero_padding(ngx_buf_t *b)
1117 {
1118 while (b->pos < b->last && *(b->pos) == 0) {
1119 b->pos++;
1120 }
1121
1122 return b->pos;
1116 } 1123 }
1117 1124
1118 1125
1119 static ngx_int_t 1126 static ngx_int_t
1120 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1127 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)