Respond pings with pongs.
authorThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Thu, 10 Oct 2013 21:33:07 +0000 (18:33 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Thu, 10 Oct 2013 21:33:07 +0000 (18:33 -0300)
Set the state of a friend as offline if timeout goes without receiving
PONG. If PING is received, send PONG. If PONG is received, set state as
online.

friend.c
friend.h
message.c
message.h

index 68deccd..03d306d 100644 (file)
--- a/friend.c
+++ b/friend.c
 #include <stdio.h>
 #include "message.h"
 
+enum {
+       STATE_OFFLINE,
+       STATE_PINGED,
+       STATE_ONLINE,
+};
+
 struct friend {
        char *name;
        char *address;
        uint16_t port;
        GInetSocketAddress *saddr;
+       int state;
 };
 
 static GSocket *usock;
@@ -64,6 +71,22 @@ int friend_send_message(struct friend *friend, char *buffer, size_t len)
        return 0;
 }
 
+void friend_timeout(struct friend *friend)
+{
+       if (friend->state == STATE_PINGED) {
+               friend->state = STATE_OFFLINE;
+       }
+}
+
+void friend_got_message(struct friend *friend, char *buffer, size_t len)
+{
+       if (len >= 4 && !strncmp(buffer, "PING", 4)) {
+               pong(friend);
+       } else if (len >= 4 && !strncmp(buffer, "PONG", 4)) {
+               friend->state = STATE_ONLINE;
+       }
+}
+
 struct cache {
        GList *friends;
 };
@@ -123,6 +146,7 @@ int cache_add_friend(struct cache *cache, char *name, char *address, uint16_t po
        g_object_unref(addr);
        cache->friends = g_list_append(cache->friends, friend);
        ping(friend);
+       friend->state = STATE_PINGED;
        return 0;
 }
 
index 76a22bd..efe5f65 100644 (file)
--- a/friend.h
+++ b/friend.h
@@ -38,4 +38,7 @@ struct friend *friend_get_by_address(GInetAddress *address, uint16_t port);
 
 char *friend_get_name();
 
+void friend_timeout(struct friend *friend);
+void friend_got_message(struct friend *friend, char *buffer, size_t len);
+
 #endif
index 25b5160..8c6dafd 100644 (file)
--- a/message.c
+++ b/message.c
@@ -26,6 +26,7 @@
 gboolean ping_timeout(gpointer data)
 {
        struct friend *friend = data;
+       friend_timeout(friend);
        return G_SOURCE_REMOVE;
 }
 
@@ -58,7 +59,7 @@ gboolean message_incoming(GIOChannel *channel, GIOCondition cond, gpointer data)
                friend = friend_get_by_address(iaddress, port);
                if (friend) {
                        printf("got message from %s\n", friend_get_name(friend));
-                       g_source_remove_by_user_data(friend);
+                       friend_got_message(friend, buffer, len);
                } else {
                        printf("could not find friend from address %s\n", g_inet_address_to_string(iaddress));
                }
@@ -77,7 +78,16 @@ int message_init(GSocket *sock)
 
 int ping(struct friend *friend)
 {
+       int err;
        char ping[5] = "PING";
-       friend_send_message(friend, ping, 4);
-       g_timeout_add(2000, ping_timeout, friend);
+       err = friend_send_message(friend, ping, 4);
+       if (!err)
+               g_timeout_add(2000, ping_timeout, friend);
+       return err;
+}
+
+int pong(struct friend *friend)
+{
+       char pong[5] = "PONG";
+       return friend_send_message(friend, pong, 4);
 }
index d2fbcc1..cd018c9 100644 (file)
--- a/message.h
+++ b/message.h
@@ -24,5 +24,6 @@
 
 int message_init(GSocket *sock);
 int ping(struct friend *friend);
+int pong(struct friend *friend);
 
 #endif