summaryrefslogtreecommitdiffstats
path: root/src/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon')
-rw-r--r--src/daemon/main.c37
-rw-r--r--src/daemon/net.c120
2 files changed, 110 insertions, 47 deletions
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 37b1a51..07da36d 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -28,6 +28,8 @@
#include "net.h"
#include "purple.h"
#include "proto_stdio.h"
+#include "tlv.h"
+#include "utils.h"
static struct _state {
int nd;
@@ -56,7 +58,7 @@ int main(int argc, char **argv)
}
} else {
if (proto_stdio_init() && setting_verbose()) {
- fprintf(stderr, "libpurple initialization failed\n");
+ fprintf(stderr, "stdio interface initialization failed\n");
}
}
@@ -77,15 +79,45 @@ int main(int argc, char **argv)
/* TODO: semi-stub */
static int __main_loop(const struct timespec * const iter_len)
{
+ struct tlv field;
+ struct tlv_packet pack;
struct timespec t;
+ char *buf = NULL;
+ size_t recvsize;
int ret = A_OK;
t = *iter_len;
+ tlv_init(&field, HEARTBEAT);
+ field.data = strdup(heartbeat_server);
+ field.head.size = sizeof(heartbeat_server);
+ tlv_packet_init(&pack);
+ tlv_pack(&pack, &field);
+ tlv_packet_finalize(&pack);
+ tlv_destroy(&field);
+
+ /* flush any pending discovery packets from the socker,
+ * as those can be quite numerous on startup.
+ */
+ net_flush_read_buffer(__progstate.nd);
- while (!ret) {
+ while (ret != ERROR) {
+ ret = net_getlastdata(__progstate.nd, &buf, &recvsize);
+
+ if (ret == A_OK) {
+ /* we're only sending one TLV per packet as of now,
+ * so no need to save the pointer for further parsing
+ */
+ ret = tlv_get(buf, &field, NULL);
+ if (ret == A_OK && field.head.type == HEARTBEAT && !(strcmp(field.data, heartbeat_device))) {
+ /* error checking? what error checking? */
+ ret = net_send(__progstate.nd, pack.data, pack.cursor + 1);
+ }
+ }
nanosleep(&t, NULL);
}
+ tlv_packet_destroy(&pack);
+
return ret;
}
@@ -94,5 +126,6 @@ static void cleanup(void)
purple_close();
proto_stdio_close();
net_close(__progstate.nd);
+ __progstate.nd = 0;
settings_cleanup();
}
diff --git a/src/daemon/net.c b/src/daemon/net.c
index 62172fe..640bd28 100644
--- a/src/daemon/net.c
+++ b/src/daemon/net.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <rin/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -34,6 +35,7 @@
#include <limits.h>
#include "settings.h"
#include "net.h"
+#include "utils.h"
struct netstate {
struct timespec lastreply;
@@ -43,8 +45,10 @@ struct netstate {
pthread_t listner;
char *data;
size_t bufsize;
+ ssize_t recvsize;
unsigned int available;
- int status;
+ int sock_status;
+ int buffer_status;
pthread_mutex_t mutex;
struct sockaddr_in clientaddr;
};
@@ -98,7 +102,8 @@ int net_init(const unsigned short int port)
state[i].data = malloc(MTU);
memset(state[i].data, 0, MTU);
state[i].bufsize = MTU;
- state[i].status = NONEWDATA;
+ state[i].sock_status = NONEWDATA;
+ state[i].buffer_status = NONEWDATA;
pthread_mutex_init(&state[i].mutex, NULL);
if (pthread_create(&state[i].listner, NULL, dolisten, state + i)) {
@@ -137,13 +142,14 @@ int net_close(int nd)
return ret;
}
-int net_getlastdata(int nd, char ** const data)
+int net_getlastdata(int nd, char ** const data, size_t *recvsize)
{
+ size_t size;
int ret;
if (nd > count || nd < 1 || state[--nd].available) {
ret = ERROR;
- } else if (!(ret = state[nd].status)) {
+ } else if (!(ret = state[nd].buffer_status)) {
if (!data) {
ret = ERROR;
goto out;
@@ -151,10 +157,13 @@ int net_getlastdata(int nd, char ** const data)
*data = malloc(MTU);
}
+ size = state[nd].recvsize;
memset(*data, 0, MTU);
- memcpy(*data, state[nd].data, MTU);
+ memcpy(*data, state[nd].data, size);
+ *recvsize = size;
}
+ state[nd].buffer_status = NONEWDATA;
out:
return ret;
}
@@ -162,27 +171,11 @@ out:
int net_send(int nd, const char * const buf, size_t buf_size)
{
int ret = A_OK;
- ssize_t sent;
- struct timespec now;
- if (nd > count || nd < 1 || state[--nd].available || state[nd].status != A_OK) {
+ if (nd > count || nd < 1 || state[nd - 1].available) {
ret = ERROR;
} else {
- if (setting_verbose() >= INFO) {
- clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- fprintf(stderr, "Sending DATA, timestap: %li \n", now.tv_sec);
- }
-
- sent = sendto( state[nd].sock, buf, buf_size, MSG_DONTWAIT,
- (struct sockaddr *) &state[nd].clientaddr,
- sizeof(state[nd].clientaddr));
-
- if (sent == -1) {
- ret = DEAD;
- if (setting_verbose() >= ERR) {
- fprintf(stderr, "Sending packet to %s failed.\n", inet_ntoa(state[nd].clientaddr.sin_addr));
- }
- }
+ ret = net_send_addr(nd, buf, buf_size, &state[nd - 1].clientaddr);
}
return ret;
@@ -194,13 +187,12 @@ int net_send_addr(int nd, const char * const buf, size_t buf_size, const struct
ssize_t sent;
struct timespec now;
-
if (nd > count || nd < 1 || state[--nd].available) {
ret = ERROR;
} else {
if (setting_verbose() >= INFO) {
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- fprintf(stderr, "Sending DATA, timestap: %li \n", now.tv_sec);
+ fprintf(stderr, "Sending packet to %s, timestap: %li \n", inet_ntoa(state[nd].clientaddr.sin_addr), now.tv_sec);
}
sent = sendto( state[nd].sock, buf, buf_size, MSG_DONTWAIT,
@@ -218,46 +210,78 @@ int net_send_addr(int nd, const char * const buf, size_t buf_size, const struct
return ret;
}
+void net_flush_read_buffer(int nd)
+{
+ struct netstate *st;
+ int cancelstate;
+ struct timespec now;
+ struct timespec later;
+ struct timespec delta;
+
+ if (setting_verbose() >= INFO) {
+ fprintf(stderr, "acquiring net mutex\n");
+ }
+
+ if (!(nd > count || nd < 1 || state[--nd].available || state[nd].sock_status != A_OK)) {
+ st = state + nd;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate);
+ pthread_mutex_lock(&st->mutex);
+
+ if (setting_verbose() >= INFO) {
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+ fprintf(stderr, "flushing netsocket\n");
+ }
+
+ do {
+ st->sock_status = getpacket(st->data, st->bufsize, &st->recvsize, st->sock, &st->clientaddr);
+ } while(st->sock_status);
+
+ if (setting_verbose() >= INFO) {
+ clock_gettime(CLOCK_MONOTONIC_RAW, &later);
+ delta = rin_time_sub(&later, &now);
+ fprintf(stderr, "finished flushing netsocket in %lis%lins\n", delta.tv_sec, delta.tv_nsec);
+ }
+
+ pthread_mutex_unlock(&st->mutex);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelstate);
+ pthread_testcancel();
+ }
+}
+
static void *dolisten(void * state)
{
struct timespec now;
- struct timespec wait = {0, 10 * 1000 * 1000}; /* 10 ms */
+ struct timespec wait = {0, 1 * 1000 * 1000}; /* 1 ms */
struct netstate *st;
- ssize_t recvbufsize;
int cancelstate;
int oldstatus = DEAD;
- char *ipstring;
st = state;
do {
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelstate);
pthread_mutex_lock(&st->mutex);
- clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- st->status = getpacket(st->data, st->bufsize, &recvbufsize, st->sock, &st->clientaddr);
+ st->sock_status = getpacket(st->data, st->bufsize, &st->recvsize, st->sock, &st->clientaddr);
- if (!st->status) {
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+ if (!st->sock_status) {
st->lastreply = now;
+ st->buffer_status = A_OK;
}
/* no packets in five seconds */
- if ((now.tv_sec - st->lastreply.tv_sec) >= 5) {
- st->status = DEAD;
- } else {
- st->status = A_OK;
- }
+ if ((now.tv_sec - st->lastreply.tv_sec) >= 20) {
+ st->sock_status = DEAD;
+ };
- if (oldstatus != st->status)
- {
- oldstatus = st->status;
- if (st->status == DEAD) {
+ if (oldstatus != st->sock_status && st->sock_status != NONEWDATA) {
+ oldstatus = st->sock_status;
+ if (st->sock_status == DEAD) {
/* this timestamp is arbitraty */
setting_verbose() >= INFO ? fprintf(stderr, "Connection with the client has been lost. Last reply since: %li \n", st->lastreply.tv_sec) : 0;
- } else if (st->status == A_OK) {
- ipstring = inet_ntoa(st->clientaddr.sin_addr);
- setting_verbose() >= INFO ? fprintf(stderr, "Successful incoming connection from %s\n", ipstring) : 0;
}
}
+
pthread_mutex_unlock(&st->mutex);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelstate);
pthread_testcancel();
@@ -273,6 +297,7 @@ static int getpacket(char *data, size_t buffsize, ssize_t *recvbufsize, int sock
{
static struct pollfd pfd = {0};
int ret;
+ char *ipstring;
socklen_t sender_len = sizeof(*sender);
if (!pfd.fd) {
@@ -288,10 +313,15 @@ static int getpacket(char *data, size_t buffsize, ssize_t *recvbufsize, int sock
ret = NONEWDATA;
} else if (pfd.revents & POLLIN) {
*recvbufsize = recvfrom(sock, data, buffsize, MSG_DONTWAIT, (struct sockaddr *) sender, &sender_len);
- ret = A_OK;
+ if (*recvbufsize < 0) {
+ ret = ERR;
+ } else {
+ ipstring = inet_ntoa(sender->sin_addr);
+ setting_verbose() >= INFO ? fprintf(stderr, "packet from %s received\n", ipstring) : 0;
+ ret = A_OK;
+ }
} else {
ret = NONEWDATA;
}
-
return ret;
}