Browse Source

* refactor f2b_csocket_*() : hide f2b_csock_t *handler

master
Alex 'AdUser' Z 4 years ago
parent
commit
4873582cc7
  1. 7
      src/csocket-test.c
  2. 76
      src/csocket.c
  3. 8
      src/csocket.h
  4. 18
      src/daemon.c

7
src/csocket-test.c

@ -21,7 +21,6 @@ cmd_handler(const f2b_cmd_t *cmd, f2b_buf_t *res) {
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
f2b_config_t config; f2b_config_t config;
f2b_csock_t *csock = NULL;
if (argc < 2) { if (argc < 2) {
puts("Usage: csocket-test <csocket.conf>"); puts("Usage: csocket-test <csocket.conf>");
@ -37,16 +36,16 @@ int main(int argc, const char **argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if ((csock = f2b_csocket_create(config.csocket)) == NULL) { if (!f2b_csocket_create(config.csocket)) {
perror("f2b_csocket_create()"); perror("f2b_csocket_create()");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
while (run) { while (run) {
f2b_csocket_poll(csock, cmd_handler); f2b_csocket_poll(cmd_handler);
sleep(1); sleep(1);
} }
f2b_csocket_destroy(csock); f2b_csocket_destroy();
return 0; return 0;
} }

76
src/csocket.c

@ -40,7 +40,7 @@ struct f2b_csock_t {
int nlisten; int nlisten;
int nclients; int nclients;
char password[32]; char password[32];
}; } csock;
/* helpers */ /* helpers */
@ -336,69 +336,64 @@ f2b_sock_destroy(f2b_sock_t *sock) {
/* control socket-related functions */ /* control socket-related functions */
f2b_csock_t * bool
f2b_csocket_create(f2b_config_section_t *config) { f2b_csocket_create(f2b_config_section_t *config) {
f2b_csock_t *csock = NULL;
f2b_sock_t *sock = NULL; f2b_sock_t *sock = NULL;
bool need_pass = false; bool need_pass = false;
if ((csock = calloc(1, sizeof(f2b_csock_t))) == NULL) { memset(&csock, 0x0, sizeof(csock));
f2b_log_msg(log_error, "can't allocate memory for csocket struct");
return NULL;
}
for (f2b_config_param_t *p = config->param; p != NULL; p = p->next) { for (f2b_config_param_t *p = config->param; p != NULL; p = p->next) {
if (strcmp(p->name, "listen") == 0) { if (strcmp(p->name, "listen") == 0) {
if (csock->nlisten >= CSOCKET_MAX_LISTEN) { if (csock.nlisten >= CSOCKET_MAX_LISTEN) {
f2b_log_msg(log_error, "ignoring excess 'listen' directive: %s", p->value); f2b_log_msg(log_error, "ignoring excess 'listen' directive: %s", p->value);
continue; continue;
} }
if ((sock = f2b_sock_create(p->value)) != NULL) { if ((sock = f2b_sock_create(p->value)) != NULL) {
csock->listen[csock->nlisten] = sock; csock.listen[csock.nlisten] = sock;
csock->nlisten++; csock.nlisten++;
if (strncmp(p->value, "inet:", 5) == 0) if (strncmp(p->value, "inet:", 5) == 0)
need_pass = true; need_pass = true;
} }
} }
if (strcmp(p->name, "password") == 0) { if (strcmp(p->name, "password") == 0) {
strlcpy(csock->password, p->value, sizeof(csock->password)); strlcpy(csock.password, p->value, sizeof(csock.password));
} }
} }
if (csock->nlisten == 0) { if (csock.nlisten == 0) {
f2b_csocket_destroy(csock); f2b_csocket_destroy();
return NULL; return false;
} }
if (need_pass && strcmp(csock->password, "") == 0) { if (need_pass && strcmp(csock.password, "") == 0) {
snprintf(csock->password, sizeof(csock->password), "%lx+%ld", random(), time(NULL)); snprintf(csock.password, sizeof(csock.password), "%lx+%ld", random(), time(NULL));
f2b_log_msg(log_info, "set random password for control socket: %s", csock->password); f2b_log_msg(log_info, "set random password for control socket: %s", csock.password);
} }
return csock; return true;
} }
void void
f2b_csocket_destroy(f2b_csock_t *csock) { f2b_csocket_destroy() {
f2b_sock_t *sock = NULL; f2b_sock_t *sock = NULL;
f2b_conn_t *conn = NULL; f2b_conn_t *conn = NULL;
assert(csock != NULL);
for (int i = 0; i < CSOCKET_MAX_LISTEN; i++) { for (int i = 0; i < CSOCKET_MAX_LISTEN; i++) {
if ((sock = csock->listen[i]) == NULL) if ((sock = csock.listen[i]) == NULL)
continue; continue;
f2b_sock_destroy(csock->listen[i]); f2b_sock_destroy(csock.listen[i]);
csock->listen[i] = NULL; csock.listen[i] = NULL;
} }
for (int i = 0; i < CSOCKET_MAX_CLIENTS; i++) { for (int i = 0; i < CSOCKET_MAX_CLIENTS; i++) {
if ((conn = csock->clients[i]) == NULL) if ((conn = csock.clients[i]) == NULL)
continue; continue;
f2b_conn_destroy(conn); f2b_conn_destroy(conn);
csock->clients[i] = NULL; csock.clients[i] = NULL;
} }
free(csock); memset(&csock, 0x0, sizeof(csock));
return; return;
} }
void void
f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) { f2b_csocket_poll(void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) {
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
fd_set rfds, wfds; fd_set rfds, wfds;
f2b_conn_t *conn = NULL; f2b_conn_t *conn = NULL;
@ -406,22 +401,21 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t
struct sockaddr_storage addr; struct sockaddr_storage addr;
socklen_t addrlen; socklen_t addrlen;
assert(csock != NULL);
assert(cb != NULL); assert(cb != NULL);
/* loop / init */ /* loop / init */
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_ZERO(&wfds); FD_ZERO(&wfds);
for (int i = 0; i < csock->nlisten; i++) { for (int i = 0; i < csock.nlisten; i++) {
sock = csock->listen[i]->sock; sock = csock.listen[i]->sock;
FD_SET(sock, &rfds); /* watch for new connections */ FD_SET(sock, &rfds); /* watch for new connections */
nfds = max(nfds, sock); nfds = max(nfds, sock);
} }
/* watch for new data on established connections */ /* watch for new data on established connections */
for (int cnum = 0; cnum < CSOCKET_MAX_CLIENTS; cnum++) { for (int cnum = 0; cnum < CSOCKET_MAX_CLIENTS; cnum++) {
if ((conn = csock->clients[cnum]) == NULL) if ((conn = csock.clients[cnum]) == NULL)
continue; continue;
FD_SET(conn->sock, &rfds); FD_SET(conn->sock, &rfds);
if (conn->send.used) if (conn->send.used)
@ -445,23 +439,23 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t
return; /* no new data */ return; /* no new data */
/* new connection on listening socket? */ /* new connection on listening socket? */
for (int i = 0; i < csock->nlisten; i++) { for (int i = 0; i < csock.nlisten; i++) {
if (!FD_ISSET(csock->listen[i]->sock, &rfds)) if (!FD_ISSET(csock.listen[i]->sock, &rfds))
continue; continue;
/* find free connection slot */ /* find free connection slot */
int cnum = 0; int cnum = 0;
for (int cnum = 0; cnum < CSOCKET_MAX_CLIENTS; cnum++) { for (int cnum = 0; cnum < CSOCKET_MAX_CLIENTS; cnum++) {
if (csock->clients[cnum] == NULL) break; if (csock.clients[cnum] == NULL) break;
} }
int sock = -1; int sock = -1;
/* accept() new connection */ /* accept() new connection */
addrlen = sizeof(struct sockaddr_storage); addrlen = sizeof(struct sockaddr_storage);
if ((sock = accept(csock->listen[i]->sock, (struct sockaddr *) &addr, &addrlen)) < 0) { if ((sock = accept(csock.listen[i]->sock, (struct sockaddr *) &addr, &addrlen)) < 0) {
f2b_log_msg(log_error, "can't accept() new connection: %s", strerror(errno)); f2b_log_msg(log_error, "can't accept() new connection: %s", strerror(errno));
} else if (cnum < CSOCKET_MAX_CLIENTS) { } else if (cnum < CSOCKET_MAX_CLIENTS) {
if ((conn = f2b_conn_create(RBUF_SIZE, WBUF_SIZE)) != NULL) { if ((conn = f2b_conn_create(RBUF_SIZE, WBUF_SIZE)) != NULL) {
conn->flags = csock->listen[i]->flags; conn->flags = csock.listen[i]->flags;
if (csock->listen[i]->flags & CSOCKET_CONN_TYPE_UNIX) { if (csock.listen[i]->flags & CSOCKET_CONN_TYPE_UNIX) {
struct ucred peer; struct ucred peer;
socklen_t peerlen = 0; socklen_t peerlen = 0;
peerlen = sizeof(peer); peerlen = sizeof(peer);
@ -480,9 +474,9 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t
f2b_log_msg(log_debug, "new remote connection from %s, socket %d", conn->peer, sock); f2b_log_msg(log_debug, "new remote connection from %s, socket %d", conn->peer, sock);
} }
conn->sock = sock; conn->sock = sock;
conn->password = csock->password; conn->password = csock.password;
f2b_conn_update_challenge(conn); f2b_conn_update_challenge(conn);
csock->clients[cnum] = conn; csock.clients[cnum] = conn;
} else { } else {
f2b_log_msg(log_error, "can't create new connection"); f2b_log_msg(log_error, "can't create new connection");
} }
@ -493,14 +487,14 @@ f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t
} }
for (int cnum = 0; cnum < CSOCKET_MAX_CLIENTS; cnum++) { for (int cnum = 0; cnum < CSOCKET_MAX_CLIENTS; cnum++) {
if ((conn = csock->clients[cnum]) == NULL) if ((conn = csock.clients[cnum]) == NULL)
continue; continue;
retval = f2b_conn_process(conn, FD_ISSET(conn->sock, &rfds), cb); retval = f2b_conn_process(conn, FD_ISSET(conn->sock, &rfds), cb);
if (retval < 0) { if (retval < 0) {
f2b_log_msg(log_debug, "closing connection on socket %d", conn->sock); f2b_log_msg(log_debug, "closing connection on socket %d", conn->sock);
shutdown(conn->sock, SHUT_RDWR); shutdown(conn->sock, SHUT_RDWR);
f2b_conn_destroy(conn); f2b_conn_destroy(conn);
csock->clients[cnum] = NULL; csock.clients[cnum] = NULL;
} }
} /* foreach connection(s) */ } /* foreach connection(s) */
return; return;

8
src/csocket.h

@ -16,8 +16,6 @@
#define CSOCKET_CONN_TYPE_INET 0x02 #define CSOCKET_CONN_TYPE_INET 0x02
#define CSOCKET_CONN_AUTH_OK 0x04 #define CSOCKET_CONN_AUTH_OK 0x04
typedef struct f2b_csock_t f2b_csock_t;
/** /**
* @file * @file
* This file contains control socket manage routines * This file contains control socket manage routines
@ -28,13 +26,13 @@ typedef struct f2b_csock_t f2b_csock_t;
* @param spec String with socket path/address specification * @param spec String with socket path/address specification
* @returns Allocated socket struct * @returns Allocated socket struct
*/ */
f2b_csock_t * f2b_csocket_create (f2b_config_section_t *config); bool f2b_csocket_create (f2b_config_section_t *config);
/** /**
* @brief Destroy socket struct and free resources * @brief Destroy socket struct and free resources
* @param csock Socket struct * @param csock Socket struct
*/ */
void f2b_csocket_destroy(f2b_csock_t *csock); void f2b_csocket_destroy();
/** /**
* @brief Poll control socket for new messages * @brief Poll control socket for new messages
@ -42,6 +40,6 @@ void f2b_csocket_destroy(f2b_csock_t *csock);
* @param cb Callback for handling message * @param cb Callback for handling message
* @returns -1 on error, 0 on no messages, and > 0 on some messages processed * @returns -1 on error, 0 on no messages, and > 0 on some messages processed
*/ */
void f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)); void f2b_csocket_poll(void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res));
#endif /* F2B_CSOCKET_H_ */ #endif /* F2B_CSOCKET_H_ */

18
src/daemon.c

@ -63,21 +63,21 @@ void usage(int exitcode) {
} }
static time_t started = 0; static time_t started = 0;
static f2b_csock_t *csock = NULL;
#ifndef WITH_CSOCKET #ifndef WITH_CSOCKET
/* add stubs to reduce #ifdef count */ /* add stubs to reduce #ifdef count */
f2b_csock_t * bool
f2b_csocket_create (f2b_config_section_t *config) { f2b_csocket_create (f2b_config_section_t *config) {
UNUSED(path); UNUSED(path);
f2b_log_msg(log_warn, "control socket support was disabled at compile-time"); f2b_log_msg(log_warn, "control socket support was disabled at compile-time");
return NULL; return NULL;
} }
void void
f2b_csocket_destroy(f2b_csock_t *csock) { f2b_csocket_destroy() {
UNUSED(csock); return; return;
} }
int f2b_csocket_poll(f2b_csock_t *csock, void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) { int
UNUSED(csock); UNUSED(cb); return 0; f2b_csocket_poll(void (*cb)(const f2b_cmd_t *cmd, f2b_buf_t *res)) {
UNUSED(cb); return 0;
} }
void void
f2b_csocket_cmd_process(const f2b_cmd_t *cmd, f2b_buf_t *res) { f2b_csocket_cmd_process(const f2b_cmd_t *cmd, f2b_buf_t *res) {
@ -337,7 +337,7 @@ int main(int argc, char *argv[]) {
} }
if (config.csocket) { if (config.csocket) {
csock = f2b_csocket_create(config.csocket); f2b_csocket_create(config.csocket);
} }
if (config.defaults) if (config.defaults)
@ -356,7 +356,7 @@ int main(int argc, char *argv[]) {
for (f2b_jail_t *jail = jails; jail != NULL; jail = jail->next) { for (f2b_jail_t *jail = jails; jail != NULL; jail = jail->next) {
f2b_jail_process(jail); f2b_jail_process(jail);
} }
f2b_csocket_poll(csock, f2b_csocket_cmd_process); f2b_csocket_poll(f2b_csocket_cmd_process);
sleep(1); sleep(1);
if (state == logrotate && strcmp(appconfig.logdest, "file") == 0) { if (state == logrotate && strcmp(appconfig.logdest, "file") == 0) {
state = run; state = run;
@ -378,7 +378,7 @@ int main(int argc, char *argv[]) {
} }
} }
f2b_csocket_destroy(csock); f2b_csocket_destroy();
jails_stop(jails); jails_stop(jails);
jails = NULL; jails = NULL;

Loading…
Cancel
Save