]> rtime.felk.cvut.cz Git - frescor/forb.git/blobdiff - src/proto_inet.c
Added REUSEADDR to TCP socket
[frescor/forb.git] / src / proto_inet.c
index 5d49ead6c5770f9754caa9fba0b954f2f8a498f5..e2ef958572f8976d0c49cf08ee5054593dff26ea 100644 (file)
@@ -58,6 +58,8 @@
 #include <sys/types.h>
 #include <ul_log.h>
 #include <unistd.h>
+#include <forb/config.h>
+#include "discovery.h"
 
 /**
  * @file   proto_inet.c
@@ -151,21 +153,39 @@ inet_connect(forb_peer_t *peer)
        struct inet_addr *addr = peer->addr;
        int ret;
 
-       if (!addr)
+       if (!addr) {
+               ul_logerr("No address to connect\n");
                return NULL;
+       }
        ipeer = forb_malloc(sizeof(*ipeer));
        if (!ipeer)
                goto err;
        ipeer->socket = socket(PF_INET, SOCK_STREAM, 0);
-       if (!ipeer->socket)
+       if (!ipeer->socket) {
+               ul_logerr("socket(): %s\n", strerror(errno));
                goto err_free;
+       }
        sa.sin_family = AF_INET;
        sa.sin_port = addr->port;
        sa.sin_addr = addr->addr;
        ul_logdeb("connect to %s:%u\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
        ret = connect(ipeer->socket, (struct sockaddr*)&sa, sizeof(sa));
-       if (ret)
+       if (ret) {
+               ul_logerr("connect error: %s\n", strerror(errno));
+               goto err_close;
+       }
+
+       struct epoll_event ev;
+       struct inet_port *p = peer->port->desc.proto_priv;
+       memset(&ev, 0, sizeof(ev));
+       ev.events = EPOLLIN | EPOLLET;
+       ev.data.fd = ipeer->socket;
+       ret = epoll_ctl(p->epoll_fd, EPOLL_CTL_ADD, ipeer->socket, &ev);
+       if (ret) {
+               ul_logerr("epoll_ctl on connect failed: %s\n", strerror(errno));
                goto err_close;
+       }
+
 
        return ipeer;
 err_close:
@@ -185,17 +205,21 @@ inet_send(forb_peer_t *peer, const void *buf, size_t len)
 
        if (!ipeer) {
                ipeer = inet_connect(peer);
-               if (!ipeer)
+               if (!ipeer) {
                        return -1;
+               }
                peer->proto_priv = ipeer;
                
        }
 
        sent = 0;
+       ul_logdeb("send fd=%d\n", ipeer->socket);
        do {
                ret = send(ipeer->socket, buf, len, 0);
-               if (ret < 0)
+               if (ret < 0) {
+                       ul_logerr("send error: %s\n", strerror(errno));
                        return ret;
+               }
                sent += ret;
                buf += ret;
                len -= ret;
@@ -394,6 +418,28 @@ size_t inet_addr2str(char *dest, size_t maxlen, const void *addr)
        return ret;
 }
 
+#if CONFIG_FCB && CONFIG_FORB_PROTO_INET_DEFAULT
+
+#include <fcb.h>
+#include <fcb_contact_info.h>
+#include <stdlib.h>
+
+static void inet_register_cb(forb_port_t *port)
+{
+       struct inet_addr *ia;
+       
+       ia = malloc(sizeof(*ia));
+       if (!ia) return;
+
+       char *fcb_addr = getenv("FCB_ADDR");
+       if (!fcb_addr) fcb_addr = "127.0.0.1";
+       ia->addr.s_addr = inet_addr(fcb_addr);
+       ia->port = htons(FCB_TCP_PORT);
+       forb_new_peer_discovered(port, NULL, FCB_SERVER_ID, ia, "");
+}
+#else
+#define inet_register_cb NULL
+#endif
 
 static const forb_proto_t proto_inet = {
        .hello_interval = 40 /* seconds */,
@@ -405,6 +451,7 @@ static const forb_proto_t proto_inet = {
        .serialize_addr = inet_serialize_addr,
        .deserialize_addr = inet_deserialize_addr,
        .addr2str = inet_addr2str,
+       .register_cb = inet_register_cb,
 };
 
 #define MAX_INTERFACES 10
@@ -439,7 +486,8 @@ int get_local_address(int sock, struct in_addr *addr)
  * appropriately.
  */
 int
-forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on)
+forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on,
+                   uint16_t port)
 {
        int ret;       
        struct inet_port *port_priv;
@@ -499,8 +547,13 @@ forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on)
        port_priv->listen_socket = socket(PF_INET, SOCK_STREAM, 0);
        if (port_priv->listen_socket == -1) goto err_close_udp;
 
+       reuse = 1;
+       setsockopt(port_priv->listen_socket, SOL_SOCKET, SO_REUSEADDR, (int *) &reuse, sizeof(reuse));
+       if (ret)
+               goto err_close_listen;
+
        addr.sin_family = AF_INET;
-       addr.sin_port = htons(0); /* Random port */
+       addr.sin_port = htons(port);
        addr.sin_addr = listen_on;
        ret = bind(port_priv->listen_socket, (struct sockaddr *)&addr, sizeof(addr));
        if (ret != 0) goto err_close_listen;
@@ -537,13 +590,15 @@ forb_inet_port_init(struct forb_port_desc *port_desc, struct in_addr listen_on)
                        port_priv->listen_socket, &ev);
        if (ret)
                goto err_close_epoll;
-       
+
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT 
        ev.events = EPOLLIN | EPOLLET;
        ev.data.fd = port_priv->udp_socket;
        ret = epoll_ctl(port_priv->epoll_fd, EPOLL_CTL_ADD,
                        port_priv->udp_socket, &ev);
        if (ret)
                goto err_close_epoll;
+#endif
 
        port_desc->proto = &proto_inet;
        port_desc->proto_priv = port_priv;