From ecefea51f8fb028919e0fd797ba14c474510eaf2 Mon Sep 17 00:00:00 2001 From: Meinhard Zhou Date: Thu, 8 Jun 2023 16:25:21 +0800 Subject: [PATCH] fix some static bug. Signed-off-by: Meinhard Zhou --- Makefile | 5 +-- connection.c | 13 ++++++-- httpd.c | 88 +++++++++++++++++++++++++++++++++++++++------------- json.c | 1 - rawlog.c | 84 ++++++++++++++++++++++++++++++++++++------------- 5 files changed, 143 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 190b0d8..e116aec 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,14 @@ CFLAGS = -Iatop -g -O2 -lz -Wall -Wcast-align -std=gnu11 OBJS = cache.o httpd.o json.o output.o rawlog.o version.o connection.o socket.o tls.o BIN = atophttpd PREFIX := $(prefix) +CC=gcc ifneq (,$(filter $(USE_TLS),yes YES y Y 1)) CFLAGS += -lssl -lcrypto -DUSE_TLS endif all: submodule bin - gcc -o $(BIN) $(OBJS) $(CFLAGS) + $(CC) -o $(BIN) $(OBJS) $(CFLAGS) install: bin install -D -s $(BIN) $(PREFIX)/usr/bin/$(BIN) @@ -19,7 +20,7 @@ deb: bin @sh packaging/debian/makedeb.sh `pwd` bin: $(OBJS) - gcc -o $(BIN) $(OBJS) $(CFLAGS) + $(CC) -o $(BIN) $(OBJS) $(CFLAGS) %.o: %.c $(CC) -c $(CFLAGS) $*.c -o $*.o diff --git a/connection.c b/connection.c index c347e18..a4d377f 100644 --- a/connection.c +++ b/connection.c @@ -45,13 +45,16 @@ int conntype_register(connection_type* ct) { } } - printf("Connection type %s registered\n", typename); + if (type == CONN_TYPE_MAX) + return -ENOMEM; + conn_types[type] = ct; if (ct->init) { ct->init(); } + printf("Connection type %s registered\n", typename); return -errno; } @@ -134,6 +137,7 @@ int listen_to_port(int port, char* bindaddr, int af) { if (ret == -1) { perror("socket bind failed: "); close(sockfd); + sockfd = -1; continue; } @@ -141,6 +145,7 @@ int listen_to_port(int port, char* bindaddr, int af) { if (ret == -1) { perror("socket listen failed: "); close(sockfd); + sockfd = -1; continue; } @@ -148,9 +153,11 @@ int listen_to_port(int port, char* bindaddr, int af) { } error: - if (sockfd != -1) + if (sockfd != -1) { close(sockfd); - sockfd = -1; + sockfd = -1; + } + end: freeaddrinfo(res); return sockfd; diff --git a/httpd.c b/httpd.c index 153833f..9091f57 100644 --- a/httpd.c +++ b/httpd.c @@ -89,24 +89,44 @@ static char *http_content_type_html = "text/html"; static char *http_content_type_css = "text/css"; static char *http_content_type_javascript = "application/javascript"; -static void http_prepare_response(connection *conn) +static int http_prepare_response(connection *conn) { /* try to send response data in a timeout */ int onoff = 1; - setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, &onoff, sizeof(onoff)); + int ret; + ret = setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, &onoff, sizeof(onoff)); + if (ret) { + printf("failed to set socket to TCP_NODELAY\n"); + return ret; + } - fcntl(conn->fd, F_SETFL, fcntl(conn->fd, F_GETFL) & ~O_NONBLOCK); + ret = fcntl(conn->fd, F_SETFL, fcntl(conn->fd, F_GETFL) & ~O_NONBLOCK); + if (ret) { + printf("failed to set conn to blocking\n"); + return ret; + } struct timeval tv = {.tv_sec = 5, .tv_usec = 0}; - setsockopt(conn->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + ret = setsockopt(conn->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + if (ret) { + printf("failed to set socket to SNDTIMEO\n"); + return ret; + } + return 0; } static void http_response_200(connection *conn, char *buf, size_t len, char *encoding, char* content_type) { struct iovec iovs[3], *iov; + int ret; + char content[128] = {0}; + int content_length = 0; - http_prepare_response(conn); + ret = http_prepare_response(conn); + if (ret) { + goto closeconn; + } /* 1, http code */ iov = &iovs[0]; @@ -115,8 +135,6 @@ static void http_response_200(connection *conn, char *buf, size_t len, char *enc /* 2, http generic content */ iov = &iovs[1]; - char content[128] = {0}; - int content_length = 0; content_length = sprintf(content, http_generic, encoding, content_type, len); iov->iov_base = content; @@ -128,6 +146,8 @@ static void http_response_200(connection *conn, char *buf, size_t len, char *enc iov->iov_len = len; conn_writev(conn, iovs, sizeof(iovs) / sizeof(iovs[0])); + +closeconn: conn_close(conn); } @@ -358,6 +378,12 @@ static void http_process_request(char *req, connection *conn) char location[URL_LEN] = {0}; char *c; + if (strlen(req) > URL_LEN) { + http_prepare_response(conn); + conn_write(conn, http_404, strlen(http_404)); + return; + } + c = strchr(req, '?'); if (c) memcpy(location, req, c - req); @@ -411,22 +437,35 @@ static void httpd_handle_request(connection *conn) { int inbytes = 0; char httpreq[URL_LEN] = {0}; time_t timeout = httpd_now_ms() + 100; + int ret; + char *httpver; - fcntl(conn->fd, F_SETFL, fcntl(conn->fd, F_GETFL) | O_NONBLOCK); + ret = fcntl(conn->fd, F_SETFL, fcntl(conn->fd, F_GETFL) | O_NONBLOCK); + if (ret) { + printf("failed to set conn to non_blocking"); + goto close_fd; + } for ( ; ; ) { time_t now = httpd_now_ms(); if (now >= timeout) - goto closefd; + goto close_fd; struct pollfd pfd = {.fd = conn->fd, .events = POLLIN, .revents = 0}; - poll(&pfd, 1, timeout - now); + ret = poll(&pfd, 1, timeout - now); + if (ret <= 0) + { + if (ret != 0) { + goto close_fd; + } + continue; + } - int ret = conn_read(conn, inbuf + inbytes, sizeof(inbuf) - inbytes); + ret = conn_read(conn, inbuf + inbytes, sizeof(inbuf) - inbytes); if (ret < 0) { if (ret != -EAGAIN) { - goto closefd; + goto close_fd; } continue; } @@ -435,28 +474,28 @@ static void httpd_handle_request(connection *conn) { if ((inbytes >= 4) && strstr(inbuf, "\r\n\r\n")) break; - /* buf is full, but we can not search the ent of HTTP header */ + /* buf is full, but we can not search the end of HTTP header */ if (inbytes == sizeof(inbuf)) - goto closefd; + goto close_fd; } /* support GET request only */ if (strncmp("GET ", inbuf, 4)) - goto closefd; + goto close_fd; /* support HTTP 1.1 request only */ - char *httpver = strstr(inbuf, "HTTP/1.1"); + httpver = strstr(inbuf, "HTTP/1.1"); if (!httpver) - goto closefd; + goto close_fd; /* Ex, GET /hello HTTP/1.1 */ if ((httpver - inbuf > URL_LEN + 6) || (httpver - inbuf < 6)) - goto closefd; + goto close_fd; memcpy(httpreq, inbuf + 5, httpver - inbuf - 6); http_process_request(httpreq, conn); -closefd: +close_fd: conn_close(conn); return; } @@ -481,7 +520,7 @@ static void *httpd_routine(connection **listeners, char *log_path) int epollfd; int ret = 0; int nr_listener = 0; - connection *listener, *conn; + connection *listener; struct epoll_event event; epollfd = epoll_create1(0); @@ -533,16 +572,18 @@ static void *httpd_routine(connection **listeners, char *log_path) } listener = event.data.ptr; + connection *conn; conn = conn_create(listener->type, -1, NULL); ret = conn_accept(listener, conn); if (ret < 0) { conn_close(conn); + free(conn); continue; } httpd_handle_request(conn); - httpd_update_cache(log_path); + free(conn); } return NULL; @@ -688,6 +729,11 @@ int main(int argc, char *argv[]) hertz = sysconf(_SC_CLK_TCK); uname(&utsname); + if (config.log_path == NULL) { + printf("%s: log path is nil\n", __func__); + return -1; + } + if (rawlog_parse_all(config.log_path)) { printf("%s: rawlog parse failed\n", __func__); return -1; diff --git a/json.c b/json.c index 36869d2..f226ed9 100644 --- a/json.c +++ b/json.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "config.h" diff --git a/rawlog.c b/rawlog.c index de49ca9..52a967c 100644 --- a/rawlog.c +++ b/rawlog.c @@ -56,6 +56,7 @@ static int rawlog_rebuild_one(struct cache_t *cache) { struct cache_elem_t *elem = &cache->elems[cache->nr_elems - 1]; struct rawrecord rr; + int ret = 0; int fd = open(cache->name, O_RDONLY); if (fd < 0) { @@ -82,14 +83,19 @@ static int rawlog_rebuild_one(struct cache_t *cache) cache->nr_elems, cache->elems[0].time, cache->elems[cache->nr_elems - 1].time); struct stat statbuf; - fstat(fd, &statbuf); + ret = fstat(fd, &statbuf); + if (ret < 0) { + printf("%s: fstat \"%s\" failed: %m\n", __func__, cache->name); + ret = -errno; + goto close_fd; + } + cache->st_size = statbuf.st_size; cache->st_mtim = statbuf.st_mtim; close_fd: close(fd); - - return 0; + return ret; } static int rawlog_parse_one(const char *path) @@ -106,7 +112,12 @@ static int rawlog_parse_one(const char *path) /* if we have already build a cache, rebuild it */ cache = cache_find(path); if (cache) { - stat(path, &statbuf); + ret = stat(path, &statbuf); + if (ret < 0) { + printf("%s: stat \"%s\" failed: %m\n", __func__, path); + return -errno; + } + if (cache->st_size == statbuf.st_size) { return 0; } @@ -144,6 +155,11 @@ static int rawlog_parse_one(const char *path) /* 3, read all rawrecords, cache time&off mapping */ off = lseek(fd, 0, SEEK_CUR); + if (off < 0) { + printf("%s: move offset failed\n", __func__); + ret = -errno; + goto close_fd; + } while (1) { len = pread(fd, &rr, sizeof(rr), off); if (len < sizeof(rr)) @@ -154,7 +170,12 @@ static int rawlog_parse_one(const char *path) } /* 4, update rawlog size & st_mtim */ - fstat(fd, &statbuf); + ret = fstat(fd, &statbuf); + if (ret < 0) { + printf("%s: fstat \"%s\" failed", __func__, path); + ret = -errno; + goto close_fd; + } cache->st_size = statbuf.st_size; cache->st_mtim = statbuf.st_mtim; @@ -201,7 +222,7 @@ int rawlog_parse_all(const char *path) return 0; } -static int rawlog_uncompress_record(int fd, void *outbuf, unsigned long *outlen, long inlen) +static int rawlog_uncompress_record(int fd, void *outbuf, unsigned long *outlen, unsigned long inlen) { Byte *inbuf; int ret = 0; @@ -224,7 +245,7 @@ static int rawlog_uncompress_record(int fd, void *outbuf, unsigned long *outlen, return ret; } -static int rawlog_get_sstat(int fd, struct sstat *sstat, long len) +static int rawlog_get_sstat(int fd, struct sstat *sstat, unsigned long len) { unsigned long outlen = sizeof(struct sstat); @@ -242,6 +263,7 @@ static int rawlog_get_devtstat(int fd, struct devtstat *devtstat, struct rawreco { unsigned long outlen = sizeof(struct tstat) * rr->ndeviat; int ret; + unsigned long ntaskall = 0, nprocall = 0, nprocactive = 0, ntaskactive = 0; /* 1, allocate memory */ memset(devtstat, 0x00, sizeof(struct devtstat)); @@ -258,7 +280,7 @@ static int rawlog_get_devtstat(int fd, struct devtstat *devtstat, struct rawreco } devtstat->procactive = malloc(sizeof(struct tstat*) * rr->nactproc); - if (!devtstat->procall) { + if (!devtstat->procactive) { ret = -ENOMEM; goto free_devtstat; } @@ -269,7 +291,6 @@ static int rawlog_get_devtstat(int fd, struct devtstat *devtstat, struct rawreco goto free_devtstat; /* 3, build devtstat */ - unsigned long ntaskall = 0, nprocall = 0, nprocactive = 0, ntaskactive = 0; for ( ; ntaskall < rr->ndeviat; ntaskall++) { struct tstat *tstat = devtstat->taskall + ntaskall; @@ -335,12 +356,20 @@ static int rawlog_record_flags(int hflags, int rflags) int rawlog_get_record(time_t ts, char *labels, connection *conn) { struct rawrecord rr; - struct sstat sstat; + struct sstat *sstat; struct devtstat devtstat; ssize_t len; int fd; - int ret; + int ret = 0; + int flags; off_t off; + time_t recent_ts; + + sstat = malloc(sizeof(struct sstat)); + if (sstat == NULL) { + log_debug("can't alloc mem for sstat\n"); + return -ENOMEM; + } struct cache_t *cache = cache_get(ts, &off); if (cache) @@ -349,12 +378,16 @@ int rawlog_get_record(time_t ts, char *labels, connection *conn) log_debug("no record @%ld\n", ts); cache = cache_get_recent(); - if (!cache) - return -EIO; + if (!cache) { + ret = -EIO; + goto free_sstat; + } - time_t recent_ts = cache->elems[cache->nr_elems - 1].time; - if (ts < recent_ts) - return -EIO; + recent_ts = cache->elems[cache->nr_elems - 1].time; + if (ts < recent_ts) { + ret = -EIO; + goto free_sstat; + } off = cache->elems[cache->nr_elems - 1].off; log_debug("use recent @%ld from %s\n", cache->elems[cache->nr_elems - 1].time, cache->name); @@ -365,10 +398,17 @@ int rawlog_get_record(time_t ts, char *labels, connection *conn) fd = open(cache->name, O_RDONLY); if (fd < 0) { printf("%s: open \"%s\" failed: %m\n", __func__, cache->name); - return -errno; + ret = -errno; + goto free_sstat; + } + + ret = lseek(fd, off, SEEK_CUR); + if (ret < 0) { + printf("%s: move offset failed\n", __func__); + ret = -errno; + goto close_fd; } - lseek(fd, off, SEEK_CUR); len = read(fd, &rr, sizeof(rr)); if (len != sizeof(rr)) { printf("%s: time %ld, off %ld in %s, incomplete record\n", __func__, ts, off, cache->name); @@ -377,7 +417,7 @@ int rawlog_get_record(time_t ts, char *labels, connection *conn) } log_debug("time %ld, off %ld in %s, rr.curtime %ld\n", ts, off, cache->name, rr.curtime); - ret = rawlog_get_sstat(fd, &sstat, rr.scomplen); + ret = rawlog_get_sstat(fd, sstat, rr.scomplen); if (ret) { printf("%s: time %ld, off %ld in %s, get sstat failed\n", __func__, ts, off, cache->name); goto close_fd; @@ -389,13 +429,15 @@ int rawlog_get_record(time_t ts, char *labels, connection *conn) goto close_fd; } - int flags = rawlog_record_flags(cache->flags, rr.flags); - jsonout(flags, labels, rr.curtime, rr.interval, &devtstat, &sstat, rr.nexit, rr.noverflow, 0, conn); + flags = rawlog_record_flags(cache->flags, rr.flags); + jsonout(flags, labels, rr.curtime, rr.interval, &devtstat, sstat, rr.nexit, rr.noverflow, 0, conn); rawlog_free_devtstat(&devtstat); close_fd: close(fd); +free_sstat: + free(sstat); return ret; }