Browse Source

[core] save parsed listen addrs at startup

save parsed listen addrs at startup for reuse at runtime

srv_socket->srv_token is normalized at startup and contains IP and port.
save offset to colon, if present, or else length of string (unix socket)

At runtime, srv_token_colon can be quickly used as length of IP string
(without port) or, if not length of string, offset of stringified port
following the colon.
master
Glenn Strauss 9 months ago
parent
commit
5c2f5577b4
  1. 3
      src/base.h
  2. 82
      src/http_cgi.c
  3. 37
      src/mod_accesslog.c
  4. 15
      src/mod_magnet.c
  5. 18
      src/network.c

3
src/base.h

@ -131,7 +131,8 @@ typedef struct server_socket {
sock_addr addr;
int fd;
unsigned short is_ssl;
uint8_t is_ssl;
uint8_t srv_token_colon;
unsigned short sidx;
fdnode *fdn;

82
src/http_cgi.c

@ -96,16 +96,13 @@ http_cgi_headers (request_st * const r, http_cgi_opts * const opts, http_cgi_hea
{
/* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
/* note: string ptrs passed to cb() func must not be NULL */
int rc = 0;
const connection * const con = r->con;
server_socket * const srv_sock = con->srv_socket;
buffer * const tb = r->tmp_buf;
const char *s;
size_t n;
char buf[LI_ITOSTRING_LENGTH];
sock_addr *addr;
sock_addr addrbuf;
char b2[INET6_ADDRSTRLEN + 1];
char buf[INET6_ADDRSTRLEN + 1]; /*(also larger than LI_ITOSTRING_LENGTH)*/
/* (CONTENT_LENGTH must be first for SCGI) */
if (!opts->authorizer)
@ -237,50 +234,63 @@ http_cgi_headers (request_st * const r, http_cgi_opts * const opts, http_cgi_hea
if (buffer_is_equal_string(&r->uri.scheme, CONST_STR_LEN("https")))
rc |= cb(vdata, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
addr = &srv_sock->addr;
rc |= cb(vdata, CONST_STR_LEN("SERVER_PORT"),
buf, li_utostrn(buf,sizeof(buf),sock_addr_get_port(addr)));
switch (sock_addr_get_family(addr)) {
case AF_INET:
case AF_INET6:
if (sock_addr_is_addr_wildcard(addr)) {
const connection * const con = r->con;
const server_socket * const srv_sock = con->srv_socket;
const size_t tlen = buffer_string_length(srv_sock->srv_token);
n = srv_sock->srv_token_colon;
if (n < tlen) { /*(n != tlen)*/
s = srv_sock->srv_token->ptr+n+1;
n = tlen - (n+1);
}
else {
s = "0";
n = 1;
}
rc |= cb(vdata, CONST_STR_LEN("SERVER_PORT"), s, n);
n = 0;
switch (sock_addr_get_family(&srv_sock->addr)) {
case AF_INET:
case AF_INET6:
if (sock_addr_is_addr_wildcard(&srv_sock->addr)) {
sock_addr addrbuf;
socklen_t addrlen = sizeof(addrbuf);
if (0 == getsockname(con->fd,(struct sockaddr *)&addrbuf,&addrlen)){
addr = &addrbuf;
/* future: might add a one- or two- element cache
* or use sock_addr_cache_inet_ntop_copy_buffer() into tb */
s = sock_addr_inet_ntop(&addrbuf, buf, sizeof(buf));
if (s)
n = strlen(s);
else
s = "";
}
else {
else
s = "";
break;
}
}
s = sock_addr_inet_ntop(addr, b2, sizeof(b2)-1);
if (NULL == s) s = "";
else {
s = srv_sock->srv_token->ptr;
n = srv_sock->srv_token_colon;
}
break;
default:
default:
s = "";
break;
}
force_assert(s);
rc |= cb(vdata, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
rc |= cb(vdata, CONST_STR_LEN("SERVER_ADDR"), s, n);
if (!buffer_string_is_empty(r->server_name)) {
size_t len = buffer_string_length(r->server_name);
if (r->server_name->ptr[0] == '[') {
const char *colon = strstr(r->server_name->ptr, "]:");
if (colon) len = (colon + 1) - r->server_name->ptr;
n = buffer_string_length(r->server_name);
s = r->server_name->ptr;
if (s[0] == '[') {
const char *colon = strstr(s, "]:");
if (colon) n = (colon + 1) - s;
}
else {
const char *colon = strchr(r->server_name->ptr, ':');
if (colon) len = colon - r->server_name->ptr;
const char *colon = strchr(s, ':');
if (colon) n = colon - s;
}
rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"),
r->server_name->ptr, len);
}
else /* set to be same as SERVER_ADDR (above) */
rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
} /* else set to be same as SERVER_ADDR (above) */
rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"), s, n);
rc |= cb(vdata, CONST_STR_LEN("REMOTE_ADDR"),
CONST_BUF_LEN(con->dst_addr_buf));

37
src/mod_accesslog.c

@ -1062,38 +1062,25 @@ static int log_access_record (const request_st * const r, buffer * const b, form
break;
case FORMAT_LOCAL_ADDR:
{
/* (perf: not using getsockname() and inet_ntop_cache_get_ip())
/* (perf: not using getsockname() and
* sock_addr_cache_inet_ntop_copy_buffer())
* (still useful if admin has configured explicit listen IPs) */
const char *colon;
buffer *srvtoken = con->srv_socket->srv_token;
if (srvtoken->ptr[0] == '[') {
colon = strstr(srvtoken->ptr, "]:");
} else {
colon = strchr(srvtoken->ptr, ':');
}
if (colon) {
buffer_append_string_len(b, srvtoken->ptr, (size_t)(colon - srvtoken->ptr));
} else {
buffer_append_string_buffer(b, srvtoken);
}
const server_socket * const srv_sock = con->srv_socket;
buffer_append_string_len(b, srv_sock->srv_token->ptr,
srv_sock->srv_token_colon);
}
break;
case FORMAT_SERVER_PORT:
if (f->opt & FORMAT_FLAG_PORT_REMOTE) {
buffer_append_int(b, sock_addr_get_port(&con->dst_addr));
} else { /* if (f->opt & FORMAT_FLAG_PORT_LOCAL) *//*(default)*/
const char *colon;
buffer *srvtoken = ((server_socket*)(con->srv_socket))->srv_token;
if (srvtoken->ptr[0] == '[') {
colon = strstr(srvtoken->ptr, "]:");
} else {
colon = strchr(srvtoken->ptr, ':');
}
if (colon) {
buffer_append_string(b, colon+1);
} else {
buffer_append_int(b, con->srv->srvconf.port);
}
const server_socket * const srv_sock = con->srv_socket;
const buffer * const srv_token = srv_sock->srv_token;
const size_t tlen = buffer_string_length(srv_token);
size_t colon = srv_sock->srv_token_colon;
if (colon < tlen) /*(colon != tlen)*/
buffer_append_string_len(b, srv_token->ptr+colon+1,
tlen - (colon+1));
}
break;
case FORMAT_QUERY_STRING:

15
src/mod_magnet.c

@ -505,7 +505,7 @@ static buffer *magnet_env_get_buffer_by_id(request_st * const r, int id) {
case MAGNET_ENV_REQUEST_ORIG_URI: dest = &r->target_orig; break;
case MAGNET_ENV_REQUEST_PATH_INFO: dest = &r->pathinfo; break;
case MAGNET_ENV_REQUEST_REMOTE_IP: dest = r->con->dst_addr_buf; break;
case MAGNET_ENV_REQUEST_SERVER_ADDR:
case MAGNET_ENV_REQUEST_SERVER_ADDR: /* local IP without port */
{
const server_socket * const srv_socket = r->con->srv_socket;
dest = r->tmp_buf;
@ -519,19 +519,14 @@ static buffer *magnet_env_get_buffer_by_id(request_st * const r, int id) {
const int fd = r->con->fd;
if (0 == getsockname(fd,(struct sockaddr *)&addrbuf,&addrlen)) {
char buf[INET6_ADDRSTRLEN + 1];
const char *s = sock_addr_inet_ntop(&addrbuf, buf, sizeof(buf)-1);
const char *s = sock_addr_inet_ntop(&addrbuf, buf, sizeof(buf));
if (NULL != s)
buffer_copy_string_len(dest, s, strlen(s));
}
}
else {
buffer_copy_buffer(dest, srv_socket->srv_token);
if (dest->ptr[0] != '[' || dest->ptr[buffer_string_length(dest)-1] != ']') {
char *s = strrchr(dest->ptr, ':');
if (s != NULL) /* local IP without port */
buffer_string_set_length(dest, s - dest->ptr);
}
}
else
buffer_copy_string_len(dest, srv_socket->srv_token->ptr,
srv_socket->srv_token_colon);
break;
default:
break;

18
src/network.c

@ -197,6 +197,20 @@ static void network_merge_config(network_socket_config * const pconf, const conf
} while ((++cpv)->k_id != -1);
}
__attribute_pure__
static uint8_t network_srv_token_colon (const buffer * const b) {
const char *colon = NULL;
const char * const p = b->ptr;
if (*p == '[') {
colon = strstr(p, "]:");
if (colon) ++colon;
}
else if (*p != '/') {
colon = strchr(p, ':');
}
return colon ? (uint8_t)(colon - p) : (uint8_t)buffer_string_length(b);
}
static int network_server_init(server *srv, network_socket_config *s, buffer *host_token, size_t sidx, int stdin_fd) {
server_socket *srv_socket;
const char *host;
@ -278,6 +292,8 @@ static int network_server_init(server *srv, network_socket_config *s, buffer *ho
srv_socket->is_ssl = s->ssl_enabled;
srv_socket->srv = srv;
srv_socket->srv_token = buffer_init_buffer(host_token);
srv_socket->srv_token_colon =
network_srv_token_colon(srv_socket->srv_token);
network_srv_sockets_append(srv, srv_socket);
@ -692,6 +708,8 @@ int network_init(server *srv, int stdin_fd) {
sizeof(server_socket));
srv_socket->srv_token =
buffer_init_buffer(srv_socket->srv_token);
srv_socket->srv_token_colon =
network_srv_token_colon(srv_socket->srv_token);
network_srv_sockets_append(srv, srv_socket);
}
}

Loading…
Cancel
Save