Tidy up handling of http server socket addresses & log spam

This commit is contained in:
Jeremy Lakeman 2016-10-25 15:51:31 +10:30
parent 9feda5258c
commit 26e38e79cb
8 changed files with 36 additions and 41 deletions

4
conf.c
View File

@ -148,11 +148,11 @@ int cf_om_save()
if (r == -1)
return -1;
if (r)
INFOF("wrote %s; set mtime=%s", path, alloca_time_t(newmeta.mtime.tv_sec));
DEBUGF(config, "wrote %s; set mtime=%s", path, alloca_time_t(newmeta.mtime.tv_sec));
else if (cmp_file_meta(&meta, &newmeta) == 0)
WARNF("wrote %s; mtime not altered", path);
else
INFOF("wrote %s", path);
DEBUGF(config, "wrote %s", path);
conffile_meta = newmeta;
DEBUGF(config, "set conffile_meta=%s", alloca_file_meta(&conffile_meta));
}

View File

@ -171,9 +171,9 @@ static int app_config_set(const struct cli_parsed *parsed, struct cli_context *U
if (cf_om_set(&cf_om_root, var[i], val[i]) == -1)
return -1;
if (val[i])
INFOF("config set %s %s", var[i], alloca_str_toprint(val[i]));
DEBUGF(config, "config set %s %s", var[i], alloca_str_toprint(val[i]));
else
INFOF("config del %s", var[i]);
DEBUGF(config, "config del %s", var[i]);
changed = 1;
} else {
if (changed) {
@ -185,12 +185,12 @@ static int app_config_set(const struct cli_parsed *parsed, struct cli_context *U
}
int pid = server_pid();
if (pid) {
INFO("config sync");
DEBUG(config, "config sync");
// TODO make timeout configurable with --timeout option.
if (mdp_client_sync_config(10000) == -1)
return 3;
} else
INFO("config sync -- skipped, server not running");
DEBUGF(config, "config sync -- skipped, server not running");
}
}
if (changed) {

View File

@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "strbuf.h"
#include "strbuf_helpers.h"
#include "fdqueue.h"
#include "socket.h"
/* Generic HTTP request handling.
*
@ -200,7 +201,7 @@ struct http_request {
// The following are used for parsing the HTTP request.
time_ms_t initiate_time; // time connection was initiated
time_ms_t idle_timeout; // disconnect if no bytes received for this long
struct sockaddr_in client_sockaddr_in; // caller may supply this
struct socket_address client_addr; // caller may supply this
// The parsed HTTP request is accumulated into the following fields.
const char *verb; // points to nul terminated static string, "GET", "PUT", etc.
const char *path; // points into buffer; nul terminated

34
httpd.c
View File

@ -237,31 +237,18 @@ static void httpd_server_finalise_http_request(struct http_request *hr)
void httpd_server_poll(struct sched_ent *alarm)
{
if (alarm->poll.revents & (POLLIN | POLLOUT)) {
struct sockaddr addr;
socklen_t addr_len = sizeof addr;
struct socket_address addr;
bzero(&addr, sizeof addr);
addr.addrlen = sizeof addr.raw;
int sock;
if ((sock = accept(httpd_server_socket, &addr, &addr_len)) == -1) {
if ((sock = accept(httpd_server_socket, &addr.addr, &addr.addrlen)) == -1) {
if (errno && errno != EAGAIN)
WARN_perror("accept");
} else {
set_nonblock(sock);
++http_request_uuid_counter;
strbuf_sprintf(&log_context, "httpd/%u", http_request_uuid_counter);
struct sockaddr_in *peerip=NULL;
if (addr.sa_family == AF_INET) {
peerip = (struct sockaddr_in *)&addr; // network order
INFOF("RHIZOME HTTP SERVER, ACCEPT addrlen=%u family=%u port=%u addr=%u.%u.%u.%u",
addr_len, peerip->sin_family, peerip->sin_port,
((unsigned char*)&peerip->sin_addr.s_addr)[0],
((unsigned char*)&peerip->sin_addr.s_addr)[1],
((unsigned char*)&peerip->sin_addr.s_addr)[2],
((unsigned char*)&peerip->sin_addr.s_addr)[3]
);
} else {
INFOF("RHIZOME HTTP SERVER, ACCEPT addrlen=%u family=%u data=%s",
addr_len, addr.sa_family, alloca_tohex((unsigned char *)addr.sa_data, sizeof addr.sa_data)
);
}
INFOF("HTTP SERVER, ACCEPT %s", alloca_socket_address(&addr));
httpd_request *request = emalloc_zero(sizeof(httpd_request));
if (request == NULL) {
WHY("Cannot respond to HTTP request, out of memory");
@ -277,8 +264,7 @@ void httpd_server_poll(struct sched_ent *alarm)
++current_httpd_request_count;
request->payload_status = INVALID_RHIZOME_PAYLOAD_STATUS; // will cause FATAL unless set
request->bundle_result = INVALID_RHIZOME_BUNDLE_RESULT; // will cause FATAL unless set
if (peerip)
request->http.client_sockaddr_in = *peerip;
request->http.client_addr = addr;
request->http.uuid = http_request_uuid_counter;
request->http.handle_headers = httpd_dispatch;
request->http.debug = INDIRECT_CONFIG_DEBUG(httpd);
@ -333,12 +319,6 @@ int is_http_header_complete(const char *buf, size_t len, size_t read_since_last_
OUT();
}
static int is_from_loopback(const struct http_request *r)
{
return r->client_sockaddr_in.sin_family == AF_INET
&& ((unsigned char*)&r->client_sockaddr_in.sin_addr.s_addr)[0] == IN_LOOPBACKNET;
}
/* Return 1 if the given authorization credentials are acceptable.
* Return 0 if not.
*/
@ -358,7 +338,7 @@ static int is_authorized_restful(const struct http_client_authorization *auth)
int authorize_restful(struct http_request *r)
{
if (!is_from_loopback(r))
if (!is_sockaddr_local(&r->client_addr))
return 403;
// If a CORS Origin: header was supplied, then if it specifies a local site, then respond with
// Access-Control-Allow-Origin and Access-Control-Allow-Methods headers that permit other pages in

View File

@ -399,11 +399,11 @@ int rhizome_direct_addfile(httpd_request *r, const char *remainder)
return 404;
if (r->http.verb != HTTP_VERB_POST)
return 405;
if ( r->http.client_sockaddr_in.sin_family != AF_INET
|| r->http.client_sockaddr_in.sin_addr.s_addr != config.rhizome.api.addfile.allow_host.s_addr
if ( r->http.client_addr.addr.sa_family != AF_INET
|| r->http.client_addr.inet.sin_addr.s_addr != config.rhizome.api.addfile.allow_host.s_addr
) {
INFOF("rhizome.api.addfile request received from %s, but is only allowed from AF_INET %s",
alloca_sockaddr(&r->http.client_sockaddr_in, sizeof r->http.client_sockaddr_in),
alloca_socket_address(&r->http.client_addr),
alloca_in_addr(&config.rhizome.api.addfile.allow_host)
);
rhizome_direct_clear_temporary_files(r);

View File

@ -175,7 +175,7 @@ static struct pid_tid get_server_pid_tid()
assert(strrchr(pidfile_path, '/') != NULL);
struct pid_tid id = read_pidfile(pidfile_path);
if (id.pid == -1) {
INFOF("Unlinking stale pidfile %s", pidfile_path);
DEBUGF(server, "Unlinking stale pidfile %s", pidfile_path);
unlink(pidfile_path);
id.pid = 0;
}
@ -279,7 +279,7 @@ int server_bind()
const char *delay = getenv("SERVALD_SERVER_START_DELAY");
if (delay){
time_ms_t milliseconds = atoi(delay);
INFOF("Sleeping for %"PRId64" milliseconds", (int64_t) milliseconds);
DEBUGF(server, "Sleeping for %"PRId64" milliseconds", (int64_t) milliseconds);
sleep_ms(milliseconds);
}
@ -407,13 +407,13 @@ static int server_write_pid()
// If the existent pidfile is not locked, then it is stale, so delete it and re-try the link.
unsigned int tries = 0;
while (1) {
INFOF("link(%s, %s)", alloca_str_toprint(tmpfile_path), alloca_str_toprint(pidfile_path));
DEBUGF(server, "link(%s, %s)", alloca_str_toprint(tmpfile_path), alloca_str_toprint(pidfile_path));
if (link(tmpfile_path, pidfile_path) != -1)
break;
if (errno == EEXIST && ++tries < 2) {
struct pid_tid id = read_pidfile(pidfile_path);
if (id.pid == -1) {
INFOF("Unlinking stale pidfile %s", pidfile_path);
DEBUGF(server, "Unlinking stale pidfile %s", pidfile_path);
unlink(pidfile_path);
} else if (id.pid > 0) {
INFOF("Another daemon is running, pid=%d tid=%d", id.pid, id.tid);

View File

@ -186,6 +186,19 @@ int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address
return c;
}
int is_sockaddr_local(const struct socket_address *addr)
{
if (addr->addrlen < sizeof addr->addr.sa_family)
return 0;
switch (addr->addr.sa_family) {
case AF_INET:
return ((unsigned char*)&addr->inet.sin_addr.s_addr)[0] == IN_LOOPBACKNET ? 1 : 0;
case AF_UNIX:
return 1;
}
return 0;
}
int _esocket(struct __sourceloc __whence, int domain, int type, int protocol)
{
int fd;

View File

@ -72,6 +72,7 @@ int socket_unlink_close(int sock);
int real_sockaddr(const struct socket_address *src_addr, struct socket_address *dst_addr);
int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address *addrB);
int is_sockaddr_local(const struct socket_address *addr);
// helper functions for manipulating fragmented packet data
#define MAX_FRAGMENTS 8