#include <sys/types.h>
#include <ul_log.h>
#include <unistd.h>
+#include <forb/config.h>
+#include "discovery.h"
/**
* @file proto_inet.c
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:
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;
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 */,
.serialize_addr = inet_serialize_addr,
.deserialize_addr = inet_deserialize_addr,
.addr2str = inet_addr2str,
+ .register_cb = inet_register_cb,
};
#define MAX_INTERFACES 10
* 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;
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;
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;