diff --git a/.gitignore b/.gitignore index c9566ca..f57c870 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *.d cachesyncd cachesyncd.log +cachesync.sock +testclient diff --git a/Makefile b/Makefile index ac4ad37..c88643e 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,17 @@ # Toplevel Makefile -SRC := cachesyncd.c configfile.c logging.c multicast.c unixsock.c +SRC := cachesyncd.c configfile.c logging.c multicast.c selector.c unixsock.c CFLAGS := -O2 -Wall # ############################ -all: cachesyncd +all: cachesyncd testclient cachesyncd: $(SRC:%.c=%.o) - $(CC) $(LDFLAGS) $^ -o $@ + $(CC) $(CFLAGS) $^ -o $@ + +testclient: testclient.o + $(CC) $(CFLAGS) $^ -o $@ %.d: %.c $(CC) $(CFLAGS) -MM -c $< -o $@ @@ -17,6 +20,6 @@ cachesyncd: $(SRC:%.c=%.o) $(CC) $(CFLAGS) -o $@ -c $< clean: - rm -rf *.d *.o cachesyncd + rm -rf *.d *.o cachesyncd cachesyncd.log cachesync.sock -include $(SRC:.c=.d) diff --git a/cachesyncd.c b/cachesyncd.c index 86f91c4..1baec61 100644 --- a/cachesyncd.c +++ b/cachesyncd.c @@ -27,8 +27,7 @@ #include "configfile.h" #include "logging.h" -#include "multicast.h" -#include "unixsock.h" +#include "selector.h" #define DEFAULT_CONFIG "cachesyncd.conf" #define DEFAULT_LOGFILE "cachesyncd.log" @@ -40,18 +39,6 @@ static struct option opts[] = { {0, 0, 0, 0} }; -static void run() -{ - int usock, msock; - usock = sock_init(); - msock = mcast_init(); - - mcast_send(msock, "HALLO", 6); - - msock_close(msock); - sock_close(usock); -} - int main(int argc, char *argv[]) { char *config = DEFAULT_CONFIG; @@ -105,7 +92,7 @@ int main(int argc, char *argv[]) log_print(LOG_EVERYTIME, "cachesyncd started (pid: %d)", getpid()); - run(); + selector(); return 0; } diff --git a/multicast.c b/multicast.c index 0369970..227d094 100644 --- a/multicast.c +++ b/multicast.c @@ -96,6 +96,13 @@ int mcast_init() return -1; } + char loop = 0; + if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop))) { + log_print(LOG_WARN, "mcast_init: setsockopt(IP_MULTICAST_LOOP)"); + close(sockfd); + return -1; + } + inet_aton(mcastgroup, &multiaddr.imr_multiaddr); multiaddr.imr_interface.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; diff --git a/selector.c b/selector.c new file mode 100644 index 0000000..1afd5be --- /dev/null +++ b/selector.c @@ -0,0 +1,101 @@ +#include +#include +#include + +#include +#include +#include + +#include "logging.h" +#include "multicast.h" +#include "unixsock.h" + +#define BUF_SIZE 256 + +void selector() +{ + fd_set fdsel; + + char *buf = malloc(BUF_SIZE); + if (buf == NULL) { + log_print(LOG_ERROR, "selector: out of memory"); + return; + } + + int usock = sock_init(); + if (usock < 0) + return; + + int msock = mcast_init(); + if (msock < 0) + return; + + int usock_con = -1; + + while (1) { + struct timeval tv; + + FD_ZERO(&fdsel); + FD_SET(usock, &fdsel); + FD_SET(msock, &fdsel); + + if (usock_con != -1) + FD_SET(usock_con, &fdsel); + + tv.tv_sec = 60; + tv.tv_usec = 0; + + int ret = select(64, &fdsel, NULL, NULL, &tv); + if (ret < 0) { + log_print(LOG_ERROR, "selector: select()"); + continue; + + } else if (ret == 0) { + mcast_send(msock, "KEEPALIVE", 10); + + } else if (FD_ISSET(usock, &fdsel)) { + if (usock_con != -1) { + log_print(LOG_INFO, "selector: unix socket overflow"); + close(usock_con); + } + + usock_con = accept(usock, NULL, NULL); + if (usock_con == -1) + log_print(LOG_ERROR, "selector: accept()"); + + } else if (usock_con != -1 && FD_ISSET(usock_con, &fdsel)) { + int len = read(usock_con, buf, BUF_SIZE); + if (len > 0) + mcast_send(msock, buf, len); + + if (!strncmp(buf, "DELETE ", 7)) { + log_print(LOG_DEBUG, "delete '%s'", buf +7); + // exec unlink + + } else { + log_print(LOG_DEBUG, "recv unknown cmd via unix socket: '%s'", buf); + } + + close(usock_con); + usock_con = -1; + + } else if (FD_ISSET(msock, &fdsel)) { + int len = read(msock, buf, BUF_SIZE); + if (len <= 0) { + log_print(LOG_ERROR, "selector: multicast sock closed?"); + + } else if (!strncmp(buf, "KEEPALIVE", 10)) { + + } else if (!strncmp(buf, "DELETE ", 7)) { + log_print(LOG_DEBUG, "delete '%s'", buf +7); + // exec unlink + + } else { + log_print(LOG_DEBUG, "recv unknown cmd via multicast: '%s'", buf); + } + } + } + + msock_close(msock); + sock_close(usock); +} diff --git a/selector.h b/selector.h new file mode 100644 index 0000000..b9540d8 --- /dev/null +++ b/selector.h @@ -0,0 +1,6 @@ +#ifndef _SELECTOR_H_ +#define _SELECTOR_H_ + +void selector(); + +#endif // _SELECTOR_H_ diff --git a/testclient.c b/testclient.c new file mode 100644 index 0000000..d50057c --- /dev/null +++ b/testclient.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +#include +#include +#include + +#define FILENAME "cachesync.sock" + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + printf("$ testclient \n"); + exit(0); + } + + int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sockfd == -1) { + perror("socket()"); + exit(-1); + } + + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, FILENAME, sizeof(addr.sun_path)); + int len = sizeof(addr.sun_family) + strlen(addr.sun_path); + + if (connect(sockfd, (struct sockaddr *)&addr, len) < 0) { + perror("connect()"); + exit(-1); + } + + write(sockfd, argv[1], strlen(argv[1]) +1); + close(sockfd); + + return 0; +} diff --git a/unixsock.c b/unixsock.c index d8d203c..670d53b 100644 --- a/unixsock.c +++ b/unixsock.c @@ -55,6 +55,13 @@ int sock_init() return -1; } + ret = listen(sockfd, 5); + if (ret == -1) { + log_print(LOG_ERROR, "unixsock: listen()"); + close(sockfd); + return -1; + } + return sockfd; }