add multicast interface support
This commit is contained in:
parent
9285147699
commit
69ff5a62ca
|
@ -32,10 +32,11 @@ struct option longopts[] = {
|
||||||
{"addr", required_argument, 0, 6},
|
{"addr", required_argument, 0, 6},
|
||||||
{"maddr", required_argument, 0, 7},
|
{"maddr", required_argument, 0, 7},
|
||||||
{"port", required_argument, 0, 8},
|
{"port", required_argument, 0, 8},
|
||||||
{"ifname", required_argument, 0, 9},
|
{"if", required_argument, 0, 9},
|
||||||
|
{"mif", required_argument, 0, 10},
|
||||||
// other extended option
|
// other extended option
|
||||||
{"socket-learning", optional_argument, 0, 10},
|
{"socket-learning", optional_argument, 0, 11},
|
||||||
{"socket-always-answer", optional_argument, 0, 11},
|
{"socket-always-answer", optional_argument, 0, 12},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,7 +65,8 @@ void usage(int c) {
|
||||||
printf(" --addr listen on ip address (current: %s)\n", addr);
|
printf(" --addr listen on ip address (current: %s)\n", addr);
|
||||||
printf(" --maddr listen and request on multcast address (current: %s)\n", maddr);
|
printf(" --maddr listen and request on multcast address (current: %s)\n", maddr);
|
||||||
printf(" --port listen on port (current: %s)\n", port);
|
printf(" --port listen on port (current: %s)\n", port);
|
||||||
printf(" --ifname listen on interface for multicast (current: %s)\n", ifname);
|
printf(" --if listen on interface (current: %s)\n", ifname);
|
||||||
|
printf(" --mif listen on interface for multicast (current: %s)\n", ifname);
|
||||||
printf("\nother extended options:\n");
|
printf("\nother extended options:\n");
|
||||||
printf(" --socket-learning learn clients during listen on socket (current: %s)\n", BOOL2STR(config_client_socket_learning));
|
printf(" --socket-learning learn clients during listen on socket (current: %s)\n", BOOL2STR(config_client_socket_learning));
|
||||||
printf(" --socket-always-answer answer on socket only with useful information (current: %s)\n", BOOL2STR(config_socket_always_answer));
|
printf(" --socket-always-answer answer on socket only with useful information (current: %s)\n", BOOL2STR(config_socket_always_answer));
|
||||||
|
@ -167,14 +169,17 @@ int main(int argc, char *argv[])
|
||||||
case 9:
|
case 9:
|
||||||
ifname = optarg;
|
ifname = optarg;
|
||||||
break;
|
break;
|
||||||
// other extended option
|
|
||||||
case 10:
|
case 10:
|
||||||
|
// skip - check later after init socket
|
||||||
|
break;
|
||||||
|
// other extended option
|
||||||
|
case 11:
|
||||||
if(optarg)
|
if(optarg)
|
||||||
config_client_socket_learning = atoi(optarg);
|
config_client_socket_learning = atoi(optarg);
|
||||||
else
|
else
|
||||||
config_client_socket_learning = !config_client_socket_learning;
|
config_client_socket_learning = !config_client_socket_learning;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 12:
|
||||||
if(optarg)
|
if(optarg)
|
||||||
config_socket_always_answer = atoi(optarg);
|
config_socket_always_answer = atoi(optarg);
|
||||||
else
|
else
|
||||||
|
@ -215,6 +220,15 @@ int main(int argc, char *argv[])
|
||||||
log_error("exit with error on socket init\n");
|
log_error("exit with error on socket init\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
c = 0;
|
||||||
|
indexptr = 0;
|
||||||
|
while ((c = getopt_long(argc, argv, "vht:s:fp",longopts, &indexptr)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 10:
|
||||||
|
socket_join_mcast(optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
uloop_run();
|
uloop_run();
|
||||||
uloop_done();
|
uloop_done();
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
#include "socket_handler.h"
|
#include "socket_handler.h"
|
||||||
|
|
||||||
static struct uloop_fd server;
|
static struct uloop_fd server;
|
||||||
struct sockaddr_in6 ownaddr;
|
int info_sock = 0;
|
||||||
struct sockaddr_in6 client_addr;
|
struct sockaddr_in6 own_addr;
|
||||||
|
struct sockaddr_in6 multicast_addr;
|
||||||
|
|
||||||
int socket_info(struct socket_msg *info) {
|
int socket_info(struct socket_msg *info) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -19,7 +20,7 @@ int socket_info(struct socket_msg *info) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sendto(server.fd, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
|
ret = sendto(info_sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&multicast_addr, sizeof(multicast_addr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
log_error("socket_info: could not send message: %d\n", ret);
|
log_error("socket_info: could not send message: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bind(sock, (struct sockaddr*)&ownaddr, sizeof(ownaddr))) {
|
if(bind(sock, (struct sockaddr*)&own_addr, sizeof(own_addr))) {
|
||||||
log_error("socket_request: could not bind to addr\n");
|
log_error("socket_request: could not bind to addr\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +59,7 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sendto(sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
|
ret = sendto(sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&multicast_addr, sizeof(multicast_addr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
close(sock);
|
close(sock);
|
||||||
log_error("socket_request: could not send message: %d\n", ret);
|
log_error("socket_request: could not send message: %d\n", ret);
|
||||||
|
@ -168,40 +169,45 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
||||||
|
|
||||||
int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port) {
|
int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port) {
|
||||||
server.cb = server_cb;
|
server.cb = server_cb;
|
||||||
server.fd = usock(USOCK_UDP | USOCK_SERVER | USOCK_IPV6ONLY | USOCK_NUMERIC, socket_bind, socket_port);
|
server.fd = usock(USOCK_UDP | USOCK_SERVER | USOCK_IPV6ONLY | USOCK_NUMERIC, "::", socket_port);
|
||||||
if (server.fd < 0) {
|
if (server.fd < 0) {
|
||||||
|
log_error("socket: error create socket to recv\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
info_sock = usock(USOCK_UDP | USOCK_IPV6ONLY | USOCK_NUMERIC, socket_bind, socket_port);
|
||||||
|
if (info_sock < 0) {
|
||||||
|
log_error("socket: error create socket to send\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_addr.sin6_family = AF_INET6;
|
multicast_addr.sin6_family = AF_INET6;
|
||||||
client_addr.sin6_port = htons(atoi(socket_port));
|
multicast_addr.sin6_port = htons(atoi(socket_port));
|
||||||
client_addr.sin6_scope_id = if_nametoindex(ifname);
|
multicast_addr.sin6_scope_id = if_nametoindex(ifname);
|
||||||
|
|
||||||
ownaddr.sin6_family = AF_INET6;
|
own_addr.sin6_family = AF_INET6;
|
||||||
ownaddr.sin6_scope_id = client_addr.sin6_scope_id;
|
own_addr.sin6_scope_id = multicast_addr.sin6_scope_id;
|
||||||
|
|
||||||
if(!inet_pton(AF_INET6, socket_bind, &ownaddr.sin6_addr)) {
|
if(!inet_pton(AF_INET6, socket_bind, &own_addr.sin6_addr)) {
|
||||||
log_error("socket: could not parse address for socket_request\n");
|
log_error("socket: could not parse address for socket_request\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// listen multicast
|
// listen multicast
|
||||||
if (!inet_pton(AF_INET6, socket_maddr, &client_addr.sin6_addr)) {
|
if (!inet_pton(AF_INET6, socket_maddr, &multicast_addr.sin6_addr)) {
|
||||||
log_error("socket: invalid multicast group\n");
|
log_error("socket: invalid multicast group\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipv6_mreq mreq = {
|
if (socket_join_mcast(ifname) < 0) {
|
||||||
.ipv6mr_multiaddr = client_addr.sin6_addr,
|
|
||||||
.ipv6mr_interface = client_addr.sin6_scope_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (setsockopt(server.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1) {
|
|
||||||
log_error("socket: unable to join multicast group: %d\n", errno);
|
log_error("socket: unable to join multicast group: %d\n", errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
|
if(setsockopt(info_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
|
||||||
|
log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(setsockopt(server.fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
|
if(setsockopt(server.fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
|
||||||
log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno);
|
log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -212,6 +218,14 @@ int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socke
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int socket_join_mcast(char *ifname) {
|
||||||
|
struct ipv6_mreq mreq = {
|
||||||
|
.ipv6mr_multiaddr = multicast_addr.sin6_addr,
|
||||||
|
.ipv6mr_interface = if_nametoindex(ifname),
|
||||||
|
};
|
||||||
|
return setsockopt(server.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
|
||||||
|
}
|
||||||
|
|
||||||
void socket_close() {
|
void socket_close() {
|
||||||
uloop_fd_delete(&server);
|
uloop_fd_delete(&server);
|
||||||
//ustream_free(&(server.fd));
|
//ustream_free(&(server.fd));
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "include.h"
|
#include "include.h"
|
||||||
#include "socket_msg.h"
|
#include "socket_msg.h"
|
||||||
|
|
||||||
int socket_init();
|
int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port);
|
||||||
|
int socket_join_mcast(char *ifname);
|
||||||
void socket_close();
|
void socket_close();
|
||||||
|
|
||||||
int socket_info(struct socket_msg *info);
|
int socket_info(struct socket_msg *info);
|
||||||
|
|
Loading…
Reference in New Issue