#include <unistd.h>
#include <forb/config.h>
#include "discovery.h"
+#include <stdlib.h>
#include "iop.h" /* FIXME: Sending hello should be handled in IOP layer */
/**
#include <fcb.h>
#include <fcb_contact_info.h>
-#include <stdlib.h>
static void inet_register_cb(forb_port_t *port)
{
{
struct ifconf ifc;
struct ifreq *ifr, req[MAX_INTERFACES];
+ char *env;
+ bool loopback = false;
+ int ret;
+ struct in_addr env_addr;
+ env = getenv("FORB_EXTERNAL_IP");
+ if (env) {
+ if (inet_aton(env, &env_addr) == 0) {
+ ul_logerr("Cannot convert FORB_EXTERNAL_IP\n");
+ errno = EINVAL;
+ return -1;
+ }
+ }
ifc.ifc_len = sizeof(req);
ifc.ifc_req = req;
for (ifr = req; ifr < &req[MAX_INTERFACES]; ifr++) {
struct sockaddr_in ia;
memcpy(&ia, &ifr->ifr_addr, sizeof(ia));
- ioctl(sock, SIOCGIFFLAGS, ifr);
- if ((ifr->ifr_flags & IFF_UP) && !(ifr->ifr_flags & IFF_LOOPBACK)) {
- *addr = ia.sin_addr;
- return 0;
+ ret = ioctl(sock, SIOCGIFFLAGS, ifr);
+ if ((ret == 0) && (ifr->ifr_flags & IFF_UP)) {
+ if (env && env_addr.s_addr == ia.sin_addr.s_addr) {
+ *addr = env_addr;
+ return 0;
+ }
+ if (!(ifr->ifr_flags & IFF_LOOPBACK)) {
+ if (!env) {
+ *addr = ia.sin_addr;
+ return 0;
+ }
+ } else {
+ *addr = ia.sin_addr;
+ loopback = true;
+ }
}
}
- return -1;
+ if (env) {
+ ul_logerr("FORB_EXTERNAL_IP doesn't match local interface\n");
+ errno = ENODEV;
+ return -1;
+ }
+ if (loopback)
+ return 0;
+ else
+ return -1;
}
/**
setnonblocking(port_priv->udp_socket);
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
struct ip_mreq mreq;
inet_aton(MCAST_ADDR, &port_priv->multicast_addr);
mreq.imr_multiaddr = port_priv->multicast_addr;
IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
if (ret)
goto err_close_udp;
+#endif
addr.sin_family = AF_INET;
addr.sin_port = htons(MCAST_PORT);
}
port_priv->addr.port = addr.sin_port;
- if (listen_on.s_addr == INADDR_ANY)
- get_local_address(port_priv->listen_socket, &port_priv->addr.addr);
- else
+ if (listen_on.s_addr == INADDR_ANY) {
+ if (get_local_address(port_priv->listen_socket, &port_priv->addr.addr)) {
+ goto err_close_listen;
+ }
+ } else
port_priv->addr.addr = listen_on;
/* Initialize epoll descriptor */