diff --git a/modules/src/kc_socket.c b/modules/src/kc_socket.c index b77abb6..f97c957 100644 --- a/modules/src/kc_socket.c +++ b/modules/src/kc_socket.c @@ -83,9 +83,9 @@ static int KcSocket_join_ipv6(KcSocket *sock, const char *addr, const char *ifname); static int KcSocket_leave_ipv4(KcSocket *sock, const char *addr, const char *ifname); static int KcSocket_leave_ipv6(KcSocket *sock, const char *addr, const char *ifname); -static bool KcSocket_set_mcastif(KcSocket *sock); -static int KcSocket_set_mcastif_ipv4(KcSocket *sock, const char *ifname); -static int KcSocket_set_mcastif_ipv6(KcSocket *sock, const char *ifname); +static bool KcSocket_set_mcastif(socket_t tmp_sock, int family, const char* mcast_v4_ifname, const char* mcast_v6_ifname); +static int KcSocket_set_mcastif_ipv4(socket_t tmp_sock, const char *ifname); +static int KcSocket_set_mcastif_ipv6(socket_t tmp_sock, const char *ifname); static int KcSocket_print_addr(char *buff, size_t size, const struct sockaddr *addr, size_t addrlen); /** @@ -595,7 +595,7 @@ } // マルチキャスト用 ifname が指定されている場合は設定する。 - KcSocket_set_mcastif(sock); + KcSocket_set_mcastif(tmp_sock, rp->ai_family, info->mcast_v4_ifname, info->mcast_v6_ifname); send_size = sendto(tmp_sock, buff, size, flags, rp->ai_addr, rp->ai_addrlen); if (send_size != SOCKET_ERROR) @@ -765,6 +765,8 @@ KcSocketInfo *info = (KcSocketInfo *)sock->_info; info->mcast_v4_ifname = v4_ifname; info->mcast_v6_ifname = v6_ifname; + printf("v4 %s\n", info->mcast_v4_ifname); + printf("v6 %s\n", info->mcast_v6_ifname); } /** @@ -980,20 +982,21 @@ * @param sock 対象ソケット * @return true/false (成功/失敗) */ -static bool KcSocket_set_mcastif(KcSocket *sock) +static bool KcSocket_set_mcastif( + socket_t tmp_sock, int family, + const char* mcast_v4_ifname, const char* mcast_v6_ifname) { - KcSocketInfo *info = (KcSocketInfo *)sock->_info; int ret = SOCKET_ERROR; - switch (info->sock_family) + switch (family) { case AF_INET: - ret = (info->mcast_v4_ifname) - ? KcSocket_set_mcastif_ipv4(sock, info->mcast_v4_ifname) + ret = (mcast_v4_ifname) + ? KcSocket_set_mcastif_ipv4(tmp_sock, mcast_v4_ifname) : 0; break; case AF_INET6: - ret = (info->mcast_v6_ifname) - ? KcSocket_set_mcastif_ipv6(sock, info->mcast_v6_ifname) + ret = (mcast_v6_ifname) + ? KcSocket_set_mcastif_ipv6(tmp_sock, mcast_v6_ifname) : 0; break; default: @@ -1006,33 +1009,29 @@ /** * マルチキャストを送信するためのインタフェースを設定します(IPv4)。 * - * @param sock 対象ソケット + * @param sock 対象一時ソケット * @param ifname インタフェース名 * @return 0/-1 (成功/失敗) */ -static int KcSocket_set_mcastif_ipv4(KcSocket *sock, const char *ifname) +static int KcSocket_set_mcastif_ipv4(socket_t tmp_sock, const char *ifname) { struct in_addr ifaddr; ifaddr.s_addr = (ifname != NULL) ? inet_addr(ifname) : htonl(INADDR_ANY); - - KcSocketInfo *info = (KcSocketInfo *)sock->_info; - int ret = setsockopt(info->sock_fd, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr, sizeof(ifaddr)); + int ret = setsockopt(tmp_sock, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr, sizeof(ifaddr)); return ret; } /** * マルチキャストを送信するためのインタフェースを設定します(IPv6)。 * - * @param sock 対象ソケット + * @param sock 対象一時ソケット * @param ifname インタフェース名 * @return 0/-1 (成功/失敗) */ -static int KcSocket_set_mcastif_ipv6(KcSocket *sock, const char *ifname) +static int KcSocket_set_mcastif_ipv6(socket_t tmp_sock, const char *ifname) { unsigned int ifindex = (ifname != NULL) ? if_nametoindex(ifname) : 0; - - KcSocketInfo *info = (KcSocketInfo *)sock->_info; - int ret = setsockopt(info->sock_fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)); + int ret = setsockopt(tmp_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)); return ret; } diff --git a/modules/src/kc_socket.c b/modules/src/kc_socket.c index b77abb6..f97c957 100644 --- a/modules/src/kc_socket.c +++ b/modules/src/kc_socket.c @@ -83,9 +83,9 @@ static int KcSocket_join_ipv6(KcSocket *sock, const char *addr, const char *ifname); static int KcSocket_leave_ipv4(KcSocket *sock, const char *addr, const char *ifname); static int KcSocket_leave_ipv6(KcSocket *sock, const char *addr, const char *ifname); -static bool KcSocket_set_mcastif(KcSocket *sock); -static int KcSocket_set_mcastif_ipv4(KcSocket *sock, const char *ifname); -static int KcSocket_set_mcastif_ipv6(KcSocket *sock, const char *ifname); +static bool KcSocket_set_mcastif(socket_t tmp_sock, int family, const char* mcast_v4_ifname, const char* mcast_v6_ifname); +static int KcSocket_set_mcastif_ipv4(socket_t tmp_sock, const char *ifname); +static int KcSocket_set_mcastif_ipv6(socket_t tmp_sock, const char *ifname); static int KcSocket_print_addr(char *buff, size_t size, const struct sockaddr *addr, size_t addrlen); /** @@ -595,7 +595,7 @@ } // マルチキャスト用 ifname が指定されている場合は設定する。 - KcSocket_set_mcastif(sock); + KcSocket_set_mcastif(tmp_sock, rp->ai_family, info->mcast_v4_ifname, info->mcast_v6_ifname); send_size = sendto(tmp_sock, buff, size, flags, rp->ai_addr, rp->ai_addrlen); if (send_size != SOCKET_ERROR) @@ -765,6 +765,8 @@ KcSocketInfo *info = (KcSocketInfo *)sock->_info; info->mcast_v4_ifname = v4_ifname; info->mcast_v6_ifname = v6_ifname; + printf("v4 %s\n", info->mcast_v4_ifname); + printf("v6 %s\n", info->mcast_v6_ifname); } /** @@ -980,20 +982,21 @@ * @param sock 対象ソケット * @return true/false (成功/失敗) */ -static bool KcSocket_set_mcastif(KcSocket *sock) +static bool KcSocket_set_mcastif( + socket_t tmp_sock, int family, + const char* mcast_v4_ifname, const char* mcast_v6_ifname) { - KcSocketInfo *info = (KcSocketInfo *)sock->_info; int ret = SOCKET_ERROR; - switch (info->sock_family) + switch (family) { case AF_INET: - ret = (info->mcast_v4_ifname) - ? KcSocket_set_mcastif_ipv4(sock, info->mcast_v4_ifname) + ret = (mcast_v4_ifname) + ? KcSocket_set_mcastif_ipv4(tmp_sock, mcast_v4_ifname) : 0; break; case AF_INET6: - ret = (info->mcast_v6_ifname) - ? KcSocket_set_mcastif_ipv6(sock, info->mcast_v6_ifname) + ret = (mcast_v6_ifname) + ? KcSocket_set_mcastif_ipv6(tmp_sock, mcast_v6_ifname) : 0; break; default: @@ -1006,33 +1009,29 @@ /** * マルチキャストを送信するためのインタフェースを設定します(IPv4)。 * - * @param sock 対象ソケット + * @param sock 対象一時ソケット * @param ifname インタフェース名 * @return 0/-1 (成功/失敗) */ -static int KcSocket_set_mcastif_ipv4(KcSocket *sock, const char *ifname) +static int KcSocket_set_mcastif_ipv4(socket_t tmp_sock, const char *ifname) { struct in_addr ifaddr; ifaddr.s_addr = (ifname != NULL) ? inet_addr(ifname) : htonl(INADDR_ANY); - - KcSocketInfo *info = (KcSocketInfo *)sock->_info; - int ret = setsockopt(info->sock_fd, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr, sizeof(ifaddr)); + int ret = setsockopt(tmp_sock, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr, sizeof(ifaddr)); return ret; } /** * マルチキャストを送信するためのインタフェースを設定します(IPv6)。 * - * @param sock 対象ソケット + * @param sock 対象一時ソケット * @param ifname インタフェース名 * @return 0/-1 (成功/失敗) */ -static int KcSocket_set_mcastif_ipv6(KcSocket *sock, const char *ifname) +static int KcSocket_set_mcastif_ipv6(socket_t tmp_sock, const char *ifname) { unsigned int ifindex = (ifname != NULL) ? if_nametoindex(ifname) : 0; - - KcSocketInfo *info = (KcSocketInfo *)sock->_info; - int ret = setsockopt(info->sock_fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)); + int ret = setsockopt(tmp_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)); return ret; } diff --git a/modules/test/src/test_socket.c b/modules/test/src/test_socket.c index fdcefc3..8c4c526 100644 --- a/modules/test/src/test_socket.c +++ b/modules/test/src/test_socket.c @@ -16,6 +16,7 @@ static void test_socket_stream1(void); static void test_socket_stream2(void); static void test_socket_mcast1_ipv4(void); +static void test_socket_mcast1_ipv6(void); // テスト用変数 /** @@ -28,7 +29,8 @@ ut->add(ut, UT_TESTCASE, "socket dgram1", test_socket_dgram1); ut->add(ut, UT_TESTCASE, "socket stream1", test_socket_stream1); ut->add(ut, UT_TESTCASE, "socket stream2", test_socket_stream2); - ut->add(ut, UT_TESTCASE, "socket mcast1", test_socket_mcast1_ipv4); + ut->add(ut, UT_TESTCASE, "socket mcast1 ipv4", test_socket_mcast1_ipv4); + ut->add(ut, UT_TESTCASE, "socket mcast1 ipv6", test_socket_mcast1_ipv6); } typedef struct @@ -435,3 +437,60 @@ server->join(server); KcThread_delete(server); } + +/** + * マルチキャスト送受信 + */ +static void test_socket_mcast1_ipv6(void) +{ + // 受信側 + KcThread *server = KcThread_new(test_socket_thread_echo_server); + TestSocketInfo info = { + .type = SOCK_DGRAM, + .family = AF_UNSPEC, + .addr = "::", + .service = "5000", + .mcast_addr = "ff02::1", + .mcast_iface = NULL, + .exp_recv_size = 6, + .exp_recv_data = "AAAAA", + .exp_src_addr = NULL, + .exp_src_service = NULL}; + server->start(server, &info); + + KcThread_msleep(100, false); + + // 送信側 + KcSocket *client = KcSocket_new(SOCK_DGRAM, AF_UNSPEC); + assert_not_null(client); + + client->set_ifname(client, NULL, "fe80::a00:27ff:fea0:521%enp0s3"); + // client->set_ifname(client, "::1", NULL); + int send_size = client->sendto(client, info.exp_recv_data, info.exp_recv_size, 0, info.mcast_addr, info.service); + assert_equals(info.exp_recv_size, send_size); + + // ソケット取得 + socket_t sock = client->get_socket(client); + assert_true(sock != INVALID_SOCKET); + + // タイプ確認 + int type = client->get_type(client); + assert_equals(SOCK_DGRAM, type); + + // ファミリー確認 (IPv4 [AF_INET]) + int family = client->get_family(client); + assert_equals(AF_INET6, family); + + // 応答受信 + char buff[16]; + int recv_size = client->recvfrom(client, buff, sizeof(buff), 0, NULL, 0, NULL, 0); + assert_equals(info.exp_recv_size, recv_size); + assert_equals((char *)info.exp_recv_data, buff); + bool ret = client->close(client); + assert_true(ret); + + KcSocket_delete(client); + + server->join(server); + KcThread_delete(server); +}