Mercurial > hg > nginx-quic
view src/core/ngx_parse.c @ 7286:d27aa9060c95
Stream: udp streams.
Previously, only one client packet could be processed in a udp stream session
even though multiple response packets were supported. Now multiple packets
coming from the same client address and port are delivered to the same stream
session.
If it's required to maintain a single stream of data, nginx should be
configured in a way that all packets from a client are delivered to the same
worker. On Linux and DragonFly BSD the "reuseport" parameter should be
specified for this. Other systems do not currently provide appropriate
mechanisms. For these systems a single stream of udp packets is only
guaranteed in single-worker configurations.
The proxy_response directive now specifies how many packets are expected in
response to a single client packet.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 04 Jun 2018 19:50:00 +0300 |
parents | 87cf6ddb41c2 |
children |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #include <ngx_config.h> #include <ngx_core.h> ssize_t ngx_parse_size(ngx_str_t *line) { u_char unit; size_t len; ssize_t size, scale, max; len = line->len; if (len == 0) { return NGX_ERROR; } unit = line->data[len - 1]; switch (unit) { case 'K': case 'k': len--; max = NGX_MAX_SIZE_T_VALUE / 1024; scale = 1024; break; case 'M': case 'm': len--; max = NGX_MAX_SIZE_T_VALUE / (1024 * 1024); scale = 1024 * 1024; break; default: max = NGX_MAX_SIZE_T_VALUE; scale = 1; } size = ngx_atosz(line->data, len); if (size == NGX_ERROR || size > max) { return NGX_ERROR; } size *= scale; return size; } off_t ngx_parse_offset(ngx_str_t *line) { u_char unit; off_t offset, scale, max; size_t len; len = line->len; if (len == 0) { return NGX_ERROR; } unit = line->data[len - 1]; switch (unit) { case 'K': case 'k': len--; max = NGX_MAX_OFF_T_VALUE / 1024; scale = 1024; break; case 'M': case 'm': len--; max = NGX_MAX_OFF_T_VALUE / (1024 * 1024); scale = 1024 * 1024; break; case 'G': case 'g': len--; max = NGX_MAX_OFF_T_VALUE / (1024 * 1024 * 1024); scale = 1024 * 1024 * 1024; break; default: max = NGX_MAX_OFF_T_VALUE; scale = 1; } offset = ngx_atoof(line->data, len); if (offset == NGX_ERROR || offset > max) { return NGX_ERROR; } offset *= scale; return offset; } ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec) { u_char *p, *last; ngx_int_t value, total, scale; ngx_int_t max, cutoff, cutlim; ngx_uint_t valid; enum { st_start = 0, st_year, st_month, st_week, st_day, st_hour, st_min, st_sec, st_msec, st_last } step; valid = 0; value = 0; total = 0; cutoff = NGX_MAX_INT_T_VALUE / 10; cutlim = NGX_MAX_INT_T_VALUE % 10; step = is_sec ? st_start : st_month; p = line->data; last = p + line->len; while (p < last) { if (*p >= '0' && *p <= '9') { if (value >= cutoff && (value > cutoff || *p - '0' > cutlim)) { return NGX_ERROR; } value = value * 10 + (*p++ - '0'); valid = 1; continue; } switch (*p++) { case 'y': if (step > st_start) { return NGX_ERROR; } step = st_year; max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 365); scale = 60 * 60 * 24 * 365; break; case 'M': if (step >= st_month) { return NGX_ERROR; } step = st_month; max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 30); scale = 60 * 60 * 24 * 30; break; case 'w': if (step >= st_week) { return NGX_ERROR; } step = st_week; max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 7); scale = 60 * 60 * 24 * 7; break; case 'd': if (step >= st_day) { return NGX_ERROR; } step = st_day; max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24); scale = 60 * 60 * 24; break; case 'h': if (step >= st_hour) { return NGX_ERROR; } step = st_hour; max = NGX_MAX_INT_T_VALUE / (60 * 60); scale = 60 * 60; break; case 'm': if (p < last && *p == 's') { if (is_sec || step >= st_msec) { return NGX_ERROR; } p++; step = st_msec; max = NGX_MAX_INT_T_VALUE; scale = 1; break; } if (step >= st_min) { return NGX_ERROR; } step = st_min; max = NGX_MAX_INT_T_VALUE / 60; scale = 60; break; case 's': if (step >= st_sec) { return NGX_ERROR; } step = st_sec; max = NGX_MAX_INT_T_VALUE; scale = 1; break; case ' ': if (step >= st_sec) { return NGX_ERROR; } step = st_last; max = NGX_MAX_INT_T_VALUE; scale = 1; break; default: return NGX_ERROR; } if (step != st_msec && !is_sec) { scale *= 1000; max /= 1000; } if (value > max) { return NGX_ERROR; } value *= scale; if (total > NGX_MAX_INT_T_VALUE - value) { return NGX_ERROR; } total += value; value = 0; while (p < last && *p == ' ') { p++; } } if (!valid) { return NGX_ERROR; } if (!is_sec) { if (value > NGX_MAX_INT_T_VALUE / 1000) { return NGX_ERROR; } value *= 1000; } if (total > NGX_MAX_INT_T_VALUE - value) { return NGX_ERROR; } return total + value; }