Skip to content

Commit

Permalink
Add quick-n-dirty debugging code to estimate memory usage.
Browse files Browse the repository at this point in the history
Debugging code is not compiled by default, don't use it unless you're
just trying to measure something :)
  • Loading branch information
darkk committed Mar 17, 2016
1 parent ad06706 commit 91a5b80
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 4 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
-include make.conf
OBJS := parser.o main.o redsocks.o log.o http-connect.o socks4.o socks5.o http-relay.o base.o base64.o md5.o http-auth.o utils.o redudp.o dnstc.o gen/version.o
ifeq ($(DBG_BUILD),1)
OBJS += debug.o
endif
SRCS := $(OBJS:.o=.c)
CONF := config.h
DEPS := .depend
OUT := redsocks
VERSION := 0.4

# -levent_extra is required only for `http` and `debug`
# -levent_core may be used for space reduction
LIBS := -levent
CFLAGS += -g -O2
override CFLAGS += -std=c99 -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -Wall
Expand All @@ -29,6 +35,9 @@ $(CONF):
echo "/* Unknown system, only generic firewall code is compiled */" >$(CONF) \
;; \
esac
ifeq ($(DBG_BUILD),1)
echo "#define DBG_BUILD 1" >>$(CONF)
endif

# Dependency on .git is useful to rebuild `version.c' after commit, but it breaks non-git builds.
gen/version.c: *.c *.h gen/.build
Expand Down
159 changes: 159 additions & 0 deletions debug.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/* redsocks - transparent TCP-to-proxy redirector
* Copyright (C) 2007-2011 Leonid Evdokimov <[email protected]>
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

#include "parser.h"
#include "main.h"
#include "log.h"
#include "utils.h"
#include <event2/http.h>
#include <event2/buffer.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct debug_instance_t {
int configured;
char* http_ip;
uint16_t http_port;
struct evhttp* http_server;
} debug_instance;

static debug_instance instance = {
.configured = 0,
};

static parser_entry debug_entries[] =
{
{ .key = "http_ip", .type = pt_pchar },
{ .key = "http_port", .type = pt_uint16 },
{ }
};

static int debug_onenter(parser_section *section)
{
if (instance.configured) {
parser_error(section->context, "only one instance of debug is valid");
return -1;
}
memset(&instance, 0, sizeof(instance));
for (parser_entry *entry = &section->entries[0]; entry->key; entry++)
entry->addr =
(strcmp(entry->key, "http_ip") == 0) ? (void*)&instance.http_ip:
(strcmp(entry->key, "http_port") == 0) ? (void*)&instance.http_port :
NULL;
return 0;
}

static int debug_onexit(parser_section *section)
{
instance.configured = 1;
if (!instance.http_ip)
instance.http_ip = strdup("localhost");
return 0;
}

static parser_section debug_conf_section =
{
.name = "debug",
.entries = debug_entries,
.onenter = debug_onenter,
.onexit = debug_onexit,
};

static void debug_meminfo_json(struct evhttp_request *req, void *arg)
{
UNUSED(arg);

struct evbuffer* body = evbuffer_new();
evbuffer_add(body, "{", 1);

FILE* fd = fopen("/proc/vmstat", "r");
while (!feof(fd)) {
char buf[64];
size_t pages;
if (fscanf(fd, "%63s %zu", buf, &pages) == 2 && strncmp(buf, "nr_", 3) == 0) {
evbuffer_add_printf(body, "\"%s\": %zu, ", buf, pages);
}
for (int c = 0; c != EOF && c != '\n'; c = fgetc(fd))
;
}
fclose(fd);

size_t vmsize, rss, share, text, z, data;
fd = fopen("/proc/self/statm", "r");
if (fscanf(fd, "%zu %zu %zu %zu %zu %zu %zu", &vmsize, &rss, &share, &text, &z, &data, &z) == 7) {
evbuffer_add_printf(body,
"\"vmsize\": %zu, \"vmrss\": %zu, \"share\": %zu, \"text\": %zu, \"data\": %zu, ",
vmsize, rss, share, text, data);

}
fclose(fd);
evbuffer_add_printf(body, "\"getpagesize\": %d}", getpagesize());

evhttp_send_reply(req, HTTP_OK, NULL, body);
evbuffer_free(body);
}

static int debug_fini();

static int debug_init(struct event_base* evbase)
{
if (!instance.http_port)
return 0;

instance.http_server = evhttp_new(evbase);
if (!instance.http_server) {
log_errno(LOG_ERR, "evhttp_new()");
goto fail;
}

if (evhttp_bind_socket(instance.http_server, instance.http_ip, instance.http_port) != 0) {
log_errno(LOG_ERR, "evhttp_bind_socket()");
goto fail;
}

if (evhttp_set_cb(instance.http_server, "/debug/meminfo.json", debug_meminfo_json, NULL) != 0) {
log_errno(LOG_ERR, "evhttp_set_cb()");
goto fail;
}

return 0;

fail:
debug_fini();
return -1;
}

static int debug_fini()
{
if (instance.http_server) {
evhttp_free(instance.http_server);
instance.http_server = 0;
}
free(instance.http_ip);
memset(&instance, 0, sizeof(instance));
return 0;
}

app_subsys debug_subsys =
{
.init = debug_init,
.fini = debug_fini,
.conf_section = &debug_conf_section,
};

/* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */
/* vim:set foldmethod=marker foldlevel=32 foldmarker={,}: */
11 changes: 8 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,19 @@
#include "main.h"
#include "utils.h"
#include "version.h"
#include "config.h"

extern app_subsys redsocks_subsys;
extern app_subsys debug_subsys;
extern app_subsys base_subsys;
extern app_subsys redudp_subsys;
extern app_subsys dnstc_subsys;

app_subsys *subsystems[] = {
&redsocks_subsys,
#ifdef DBG_BUILD
&debug_subsys,
#endif
&base_subsys,
&redudp_subsys,
&dnstc_subsys,
Expand Down Expand Up @@ -118,12 +123,12 @@ int main(int argc, char **argv)
if (conftest)
return EXIT_SUCCESS;

event_init();
struct event_base* evbase = event_init();
memset(terminators, 0, sizeof(terminators));

FOREACH(ss, subsystems) {
if ((*ss)->init) {
error = (*ss)->init();
error = (*ss)->init(evbase);
if (error)
goto shutdown;
}
Expand Down Expand Up @@ -167,7 +172,7 @@ int main(int argc, char **argv)
if ((*ss)->fini)
(*ss)->fini();

event_base_free(NULL);
event_base_free(evbase);

return !error ? EXIT_SUCCESS : EXIT_FAILURE;
}
Expand Down
4 changes: 3 additions & 1 deletion main.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#include "parser.h"

struct event_base;

typedef struct app_subsys_t {
int (*init)();
int (*init)(struct event_base*);
int (*fini)();
parser_section* conf_section;
} app_subsys;
Expand Down

0 comments on commit 91a5b80

Please sign in to comment.