comparison src/event/quic/ngx_event_quic_tokens.c @ 8763:4117aa7fa38e quic

QUIC: connection migration. The patch adds proper transitions between multiple networking addresses that can be used by a single quic connection. New networking paths are validated using PATH_CHALLENGE/PATH_RESPONSE frames.
author Vladimir Homutov <vl@nginx.com>
date Thu, 29 Apr 2021 15:35:02 +0300
parents b4e6b7049984
children 2029a30863e2
comparison
equal deleted inserted replaced
8762:12f18e0bca09 8763:4117aa7fa38e
13 13
14 #define NGX_QUIC_MAX_TOKEN_SIZE 64 14 #define NGX_QUIC_MAX_TOKEN_SIZE 64
15 /* SHA-1(addr)=20 + sizeof(time_t) + retry(1) + odcid.len(1) + odcid */ 15 /* SHA-1(addr)=20 + sizeof(time_t) + retry(1) + odcid.len(1) + odcid */
16 16
17 17
18 static void ngx_quic_address_hash(ngx_connection_t *c, ngx_uint_t no_port, 18 static void ngx_quic_address_hash(struct sockaddr *sockaddr, socklen_t socklen,
19 u_char buf[20]); 19 ngx_uint_t no_port, u_char buf[20]);
20 20
21 21
22 ngx_int_t 22 ngx_int_t
23 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, u_char *secret, 23 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, u_char *secret,
24 u_char *token) 24 u_char *token)
44 return NGX_OK; 44 return NGX_OK;
45 } 45 }
46 46
47 47
48 ngx_int_t 48 ngx_int_t
49 ngx_quic_new_token(ngx_connection_t *c, u_char *key, ngx_str_t *token, 49 ngx_quic_new_token(ngx_connection_t *c, struct sockaddr *sockaddr,
50 ngx_str_t *odcid, time_t exp, ngx_uint_t is_retry) 50 socklen_t socklen, u_char *key, ngx_str_t *token, ngx_str_t *odcid,
51 time_t exp, ngx_uint_t is_retry)
51 { 52 {
52 int len, iv_len; 53 int len, iv_len;
53 u_char *p, *iv; 54 u_char *p, *iv;
54 EVP_CIPHER_CTX *ctx; 55 EVP_CIPHER_CTX *ctx;
55 const EVP_CIPHER *cipher; 56 const EVP_CIPHER *cipher;
56 57
57 u_char in[NGX_QUIC_MAX_TOKEN_SIZE]; 58 u_char in[NGX_QUIC_MAX_TOKEN_SIZE];
58 59
59 ngx_quic_address_hash(c, !is_retry, in); 60 ngx_quic_address_hash(sockaddr, socklen, !is_retry, in);
60 61
61 p = in + 20; 62 p = in + 20;
62 63
63 p = ngx_cpymem(p, &exp, sizeof(time_t)); 64 p = ngx_cpymem(p, &exp, sizeof(time_t));
64 65
123 return NGX_OK; 124 return NGX_OK;
124 } 125 }
125 126
126 127
127 static void 128 static void
128 ngx_quic_address_hash(ngx_connection_t *c, ngx_uint_t no_port, u_char buf[20]) 129 ngx_quic_address_hash(struct sockaddr *sockaddr, socklen_t socklen,
130 ngx_uint_t no_port, u_char buf[20])
129 { 131 {
130 size_t len; 132 size_t len;
131 u_char *data; 133 u_char *data;
132 ngx_sha1_t sha1; 134 ngx_sha1_t sha1;
133 struct sockaddr_in *sin; 135 struct sockaddr_in *sin;
134 #if (NGX_HAVE_INET6) 136 #if (NGX_HAVE_INET6)
135 struct sockaddr_in6 *sin6; 137 struct sockaddr_in6 *sin6;
136 #endif 138 #endif
137 139
138 len = (size_t) c->socklen; 140 len = (size_t) socklen;
139 data = (u_char *) c->sockaddr; 141 data = (u_char *) sockaddr;
140 142
141 if (no_port) { 143 if (no_port) {
142 switch (c->sockaddr->sa_family) { 144 switch (sockaddr->sa_family) {
143 145
144 #if (NGX_HAVE_INET6) 146 #if (NGX_HAVE_INET6)
145 case AF_INET6: 147 case AF_INET6:
146 sin6 = (struct sockaddr_in6 *) c->sockaddr; 148 sin6 = (struct sockaddr_in6 *) sockaddr;
147 149
148 len = sizeof(struct in6_addr); 150 len = sizeof(struct in6_addr);
149 data = sin6->sin6_addr.s6_addr; 151 data = sin6->sin6_addr.s6_addr;
150 152
151 break; 153 break;
152 #endif 154 #endif
153 155
154 case AF_INET: 156 case AF_INET:
155 sin = (struct sockaddr_in *) c->sockaddr; 157 sin = (struct sockaddr_in *) sockaddr;
156 158
157 len = sizeof(in_addr_t); 159 len = sizeof(in_addr_t);
158 data = (u_char *) &sin->sin_addr; 160 data = (u_char *) &sin->sin_addr;
159 161
160 break; 162 break;
234 ngx_memcpy(&exp, p, sizeof(time_t)); 236 ngx_memcpy(&exp, p, sizeof(time_t));
235 p += sizeof(time_t); 237 p += sizeof(time_t);
236 238
237 pkt->retried = (*p++ == 1); 239 pkt->retried = (*p++ == 1);
238 240
239 ngx_quic_address_hash(c, !pkt->retried, addr_hash); 241 ngx_quic_address_hash(c->sockaddr, c->socklen, !pkt->retried, addr_hash);
240 242
241 if (ngx_memcmp(tdec, addr_hash, 20) != 0) { 243 if (ngx_memcmp(tdec, addr_hash, 20) != 0) {
242 goto bad_token; 244 goto bad_token;
243 } 245 }
244 246