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},
|
||||
{"maddr", required_argument, 0, 7},
|
||||
{"port", required_argument, 0, 8},
|
||||
{"ifname", required_argument, 0, 9},
|
||||
{"if", required_argument, 0, 9},
|
||||
{"mif", required_argument, 0, 10},
|
||||
// other extended option
|
||||
{"socket-learning", optional_argument, 0, 10},
|
||||
{"socket-always-answer", optional_argument, 0, 11},
|
||||
{"socket-learning", optional_argument, 0, 11},
|
||||
{"socket-always-answer", optional_argument, 0, 12},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -64,7 +65,8 @@ void usage(int c) {
|
|||
printf(" --addr listen on ip address (current: %s)\n", addr);
|
||||
printf(" --maddr listen and request on multcast address (current: %s)\n", maddr);
|
||||
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(" --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));
|
||||
|
@ -167,14 +169,17 @@ int main(int argc, char *argv[])
|
|||
case 9:
|
||||
ifname = optarg;
|
||||
break;
|
||||
// other extended option
|
||||
case 10:
|
||||
// skip - check later after init socket
|
||||
break;
|
||||
// other extended option
|
||||
case 11:
|
||||
if(optarg)
|
||||
config_client_socket_learning = atoi(optarg);
|
||||
else
|
||||
config_client_socket_learning = !config_client_socket_learning;
|
||||
break;
|
||||
case 11:
|
||||
case 12:
|
||||
if(optarg)
|
||||
config_socket_always_answer = atoi(optarg);
|
||||
else
|
||||
|
@ -215,6 +220,15 @@ int main(int argc, char *argv[])
|
|||
log_error("exit with error on socket init\n");
|
||||
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
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
#include "socket_handler.h"
|
||||
|
||||
static struct uloop_fd server;
|
||||
struct sockaddr_in6 ownaddr;
|
||||
struct sockaddr_in6 client_addr;
|
||||
int info_sock = 0;
|
||||
struct sockaddr_in6 own_addr;
|
||||
struct sockaddr_in6 multicast_addr;
|
||||
|
||||
int socket_info(struct socket_msg *info) {
|
||||
int ret = 0;
|
||||
|
@ -19,7 +20,7 @@ int socket_info(struct socket_msg *info) {
|
|||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer
|
|||
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) {
|
||||
close(sock);
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
client_addr.sin6_family = AF_INET6;
|
||||
client_addr.sin6_port = htons(atoi(socket_port));
|
||||
client_addr.sin6_scope_id = if_nametoindex(ifname);
|
||||
multicast_addr.sin6_family = AF_INET6;
|
||||
multicast_addr.sin6_port = htons(atoi(socket_port));
|
||||
multicast_addr.sin6_scope_id = if_nametoindex(ifname);
|
||||
|
||||
ownaddr.sin6_family = AF_INET6;
|
||||
ownaddr.sin6_scope_id = client_addr.sin6_scope_id;
|
||||
own_addr.sin6_family = AF_INET6;
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct ipv6_mreq mreq = {
|
||||
.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) {
|
||||
if (socket_join_mcast(ifname) < 0) {
|
||||
log_error("socket: unable to join multicast group: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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) {
|
||||
log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno);
|
||||
return -1;
|
||||
|
@ -212,6 +218,14 @@ int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socke
|
|||
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() {
|
||||
uloop_fd_delete(&server);
|
||||
//ustream_free(&(server.fd));
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#include "include.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();
|
||||
|
||||
int socket_info(struct socket_msg *info);
|
||||
|
|
Loading…
Reference in New Issue