Browse Source

* source/mcast : fix start()

master
Alex 'AdUser' Z 8 years ago
parent
commit
217b7006f9
  1. 30
      src/sources/mcast.c

30
src/sources/mcast.c

@ -113,7 +113,7 @@ start(cfg_t *cfg) {
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *result; struct addrinfo *result;
struct ip_mreq mreq; struct ip_mreq mreq;
int opt, ret; int opt, ret, sock = -1;
assert(cfg != NULL); assert(cfg != NULL);
@ -128,41 +128,41 @@ start(cfg_t *cfg) {
} }
for (struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next) { for (struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next) {
if (sock >= 0) {
close(sock); /* from prev iteration */
sock = -1;
}
/* create socket */ /* create socket */
if ((cfg->sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) { if ((sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) {
snprintf(cfg->error, sizeof(cfg->error), "can't create socket: %s", strerror(errno)); snprintf(cfg->error, sizeof(cfg->error), "can't create socket: %s", strerror(errno));
continue; continue;
} }
/* set non-blocking mode */ /* set non-blocking mode */
if ((opt = fcntl(cfg->sock, F_GETFL, 0)) < 0) { if ((opt = fcntl(sock, F_GETFL, 0)) < 0) {
close(cfg->sock);
continue; continue;
} }
fcntl(cfg->sock, F_SETFL, opt | O_NONBLOCK); fcntl(sock, F_SETFL, opt | O_NONBLOCK);
/* reuse address */ /* reuse address */
opt = 1; opt = 1;
setsockopt(cfg->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
/* bind to interface if set */ /* bind to interface if set */
if (cfg->iface[0]) { if (cfg->iface[0]) {
if (setsockopt(cfg->sock, SOL_SOCKET, SO_BINDTODEVICE, cfg->iface, strlen(cfg->iface)) < 0) { if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, cfg->iface, strlen(cfg->iface)) < 0) {
snprintf(cfg->error, sizeof(cfg->error), "can't bind socket to iface %s: %s", snprintf(cfg->error, sizeof(cfg->error), "can't bind socket to iface %s: %s",
cfg->iface, strerror(errno)); cfg->iface, strerror(errno));
close(cfg->sock);
continue; continue;
} }
} }
/* bind to given address */ /* bind to given address */
if (bind(cfg->sock, rp->ai_addr, rp->ai_addrlen) < 0) { if (bind(sock, rp->ai_addr, rp->ai_addrlen) < 0) {
snprintf(cfg->error, sizeof(cfg->error), "can't bind socket to addr %s: %s", snprintf(cfg->error, sizeof(cfg->error), "can't bind socket to addr %s: %s",
cfg->baddr, strerror(errno)); cfg->baddr, strerror(errno));
close(cfg->sock);
continue; continue;
} }
/* set out iface for mcast */ /* set out iface for mcast */
if (setsockopt(cfg->sock, IPPROTO_IP, IP_MULTICAST_IF, rp->ai_addr, rp->ai_addrlen) < 0) { if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, rp->ai_addr, rp->ai_addrlen) < 0) {
snprintf(cfg->error, sizeof(cfg->error), "can't set out iface for mcast: %s", snprintf(cfg->error, sizeof(cfg->error), "can't set out iface for mcast: %s",
strerror(errno)); strerror(errno));
close(cfg->sock);
continue; continue;
} }
/* IP_MULTICAST_LOOP -- default: yes */ /* IP_MULTICAST_LOOP -- default: yes */
@ -170,19 +170,19 @@ start(cfg_t *cfg) {
/* join mcast group */ /* join mcast group */
inet_pton(AF_INET, cfg->maddr, &mreq.imr_multiaddr); inet_pton(AF_INET, cfg->maddr, &mreq.imr_multiaddr);
memcpy(&mreq.imr_interface, rp->ai_addr, rp->ai_addrlen); memcpy(&mreq.imr_interface, rp->ai_addr, rp->ai_addrlen);
if (setsockopt(cfg->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
snprintf(cfg->error, sizeof(cfg->error), "can't join mcast group: %s", snprintf(cfg->error, sizeof(cfg->error), "can't join mcast group: %s",
strerror(errno)); strerror(errno));
close(cfg->sock);
continue; continue;
} }
break; /* success */ break; /* success */
} }
freeaddrinfo(result); freeaddrinfo(result);
if (cfg->sock < 0) if (sock < 0)
return false; return false;
cfg->sock = sock;
return true; return true;
} }

Loading…
Cancel
Save