📄 net_udp.c
字号:
#else rtp_message(LOG_DEBUG,"IGMPV3 src:%s\n", G_Multicast_Src); /* Join Multicast group with source filter */ if (G_IGMP_V3 != 0 && strcmp(G_Multicast_Src, "0.0.0.0") != 0) { struct ip_mreq_source imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; imr.imr_interface.s_addr = s->iface4_addr.s_addr; if (inet_aton(G_Multicast_Src, &imr.imr_sourceaddr) == 0) { rtp_message(LOG_ERR, "inet_aton failed for %s\n", G_Multicast_Src); return NULL; } if( setsockopt( s->fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char*)&imr, sizeof(struct ip_mreq_source) ) == -1 ) { socket_error("setsockopt IP_ADD_SOURCE_MEMBERSHIP"); closesocket(s->fd); free(s); return NULL; } }#endif #ifndef WIN32 if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) { socket_error("setsockopt IP_MULTICAST_LOOP"); closesocket(s->fd); free(s); return NULL; }#endif if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &s->ttl, sizeof(s->ttl)) != 0) { socket_error("setsockopt IP_MULTICAST_TTL"); closesocket(s->fd); free(s); return NULL; } if (s->iface4_addr.s_addr != 0) { if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &s->iface4_addr, sizeof(s->iface4_addr)) != 0) { closesocket(s->fd); free(s); socket_error("setsockopt IP_MULTICAST_IF"); return NULL; } } } if (addr != NULL) s->addr = strdup(addr); return s;}static void udp_exit4(socket_udp *s){ if (IN_MULTICAST(ntohl(s->addr4.s_addr))) {#ifndef HAVE_IGMP_V3 struct ip_mreq imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; if (s->iface4_addr.s_addr != 0) { imr.imr_interface.s_addr = s->iface4_addr.s_addr; } else { imr.imr_interface.s_addr = INADDR_ANY; } if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) { socket_error("setsockopt IP_DROP_MEMBERSHIP"); abort(); }#else rtp_message(LOG_DEBUG,"IGMPV3 leaving src:%s\n", G_Multicast_Src); /* Join Multicast group with source filter */ struct ip_mreq_source imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; if (s->iface4_addr.s_addr != 0) { imr.imr_interface.s_addr = s->iface4_addr.s_addr; } else { imr.imr_interface.s_addr = INADDR_ANY; } if (inet_aton(G_Multicast_Src, &imr.imr_sourceaddr) == 0) { rtp_message(LOG_ERR, "inet_aton failed for %s\n", G_Multicast_Src); abort(); } if( setsockopt( s->fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, (char*)&imr, sizeof(struct ip_mreq_source) ) == -1 ) { socket_error("setsockopt IP_DROP_SOURCE_MEMBERSHIP"); //abort(); }#endif rtp_message(LOG_INFO, "Dropped membership of multicast group"); } closesocket(s->fd); if (s->addr != NULL) free(s->addr); free(s);}static int udp_send4(socket_udp *s, const uint8_t *buffer, uint32_t buflen){ struct sockaddr_in s_in; ASSERT(s != NULL); ASSERT(s->mode == IPv4); ASSERT(buffer != NULL); ASSERT(buflen > 0); s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = s->addr4.s_addr; s_in.sin_port = htons(s->tx_port); return sendto(s->fd, buffer, buflen, 0, (struct sockaddr *) &s_in, sizeof(s_in));}#ifdef HAVE_STRUCT_IOVECstatic int udp_send_iov4(socket_udp *s, struct iovec *iov, int count){ struct sockaddr_in s_in; struct msghdr msg; ASSERT(s != NULL); ASSERT(s->mode == IPv4); ASSERT(iov != NULL); ASSERT(count > 0); s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = s->addr4.s_addr; s_in.sin_port = htons(s->tx_port); memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)&s_in; msg.msg_namelen = sizeof(s_in); msg.msg_iov = iov; msg.msg_iovlen = count; return sendmsg(s->fd, &msg, 0);}#endifstatic char *udp_host_addr4(void){ char hname[MAXHOSTNAMELEN]; struct hostent *hent; struct in_addr iaddr; if (gethostname(hname, MAXHOSTNAMELEN) != 0) { rtp_message(LOG_ERR, "Cannot get hostname!"); abort(); } hent = gethostbyname(hname); if (hent == NULL) { socket_error("Can't resolve IP address for %s", hname); return NULL; } ASSERT(hent->h_addrtype == AF_INET); memcpy(&iaddr.s_addr, hent->h_addr, sizeof(iaddr.s_addr)); strncpy(hname, inet_ntoa(iaddr), MAXHOSTNAMELEN); return xstrdup(hname);}/*****************************************************************************//* IPv6 specific functions... *//*****************************************************************************/static int udp_addr_valid6(const char *dst){#ifdef HAVE_IPv6 struct in6_addr addr6; switch (inet_pton(AF_INET6, dst, &addr6)) { case 1: return TRUE; break; case 0: return FALSE; break; case -1: rtp_message(LOG_ERR, "inet_pton failed"); errno = 0; }#endif /* HAVE_IPv6 */ UNUSED(dst); return FALSE;}static socket_udp *udp_init6(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl){#ifdef HAVE_IPv6 int reuse = 1; struct sockaddr_in6 s_in; socket_udp *s = (socket_udp *) malloc(sizeof(socket_udp)); s->mode = IPv6; s->addr = NULL; s->rx_port = rx_port; s->tx_port = tx_port; s->ttl = ttl; if (iface != NULL) { debug_msg("Not yet implemented\n"); abort(); } if (addr != NULL) { if (inet_pton(AF_INET6, addr, &s->addr6) != 1) { /* We should probably try to do a DNS lookup on the name */ /* here, but I'm trying to get the basics going first... */ debug_msg("IPv6 address conversion failed\n"); free(s); return NULL; } } s->fd = socket(AF_INET6, SOCK_DGRAM, 0); if (s->fd < 0) { socket_error("socket"); return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEADDR"); return NULL; }#ifdef SO_REUSEPORT if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEPORT"); return NULL; }#endif memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_port = htons(rx_port);#ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in);#endif s_in.sin6_addr = in6addr_any; if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) { socket_error("bind"); return NULL; } if (addr != NULL && IN6_IS_ADDR_MULTICAST(&(s->addr6))) { unsigned int loop = 1; struct ipv6_mreq imr;#ifdef MUSICA_IPV6 imr.i6mr_interface = 1; imr.i6mr_multiaddr = s->addr6;#else imr.ipv6mr_multiaddr = s->addr6; imr.ipv6mr_interface = 0;#endif if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &imr, sizeof(imr)) != 0) { socket_error("setsockopt IPV6_ADD_MEMBERSHIP"); return NULL; } if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &loop, sizeof(loop)) != 0) { socket_error("setsockopt IPV6_MULTICAST_LOOP"); return NULL; } if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof(ttl)) != 0) { socket_error("setsockopt IPV6_MULTICAST_HOPS"); return NULL; } } ASSERT(s != NULL); if (addr != NULL) { s->addr = strdup(addr); } return s;#else UNUSED(addr); UNUSED(iface); UNUSED(rx_port); UNUSED(tx_port); UNUSED(ttl); return NULL;#endif}static void udp_exit6(socket_udp *s){#ifdef HAVE_IPv6 if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) { struct ipv6_mreq imr;#ifdef MUSICA_IPV6 imr.i6mr_interface = 1; imr.i6mr_multiaddr = s->addr6;#else imr.ipv6mr_multiaddr = s->addr6; imr.ipv6mr_interface = 0;#endif if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ipv6_mreq)) != 0) { socket_error("setsockopt IPV6_DROP_MEMBERSHIP"); abort(); } } closesocket(s->fd); if (s->addr != NULL) { free(s->addr); } free(s);#else UNUSED(s);#endif /* HAVE_IPv6 */}static int udp_send6(socket_udp *s, const uint8_t *buffer, uint32_t buflen){#ifdef HAVE_IPv6 struct sockaddr_in6 s_in; ASSERT(s != NULL); ASSERT(s->mode == IPv6); ASSERT(buffer != NULL); ASSERT(buflen > 0); memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_addr = s->addr6; s_in.sin6_port = htons(s->tx_port);#ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in);#endif return sendto(s->fd, buffer, buflen, 0, (struct sockaddr *) &s_in, sizeof(s_in));#else UNUSED(s); UNUSED(buffer); UNUSED(buflen); return -1;#endif}#ifdef HAVE_STRUCT_IOVECstatic int udp_send_iov6(socket_udp *s, struct iovec *iov, int count){#ifdef HAVE_IPv6 struct sockaddr_in6 s_in; struct msghdr msg; ASSERT(s != NULL); ASSERT(s->mode == IPv6); memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_addr = s->addr6; s_in.sin6_port = htons(s->tx_port);#ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in);#endif memset(&msg, 0, sizeof(msg)); msg.msg_name = &s_in; msg.msg_namelen = sizeof(s_in); msg.msg_iov = iov; msg.msg_iovlen = count; /* handled in memset, don't need HAVE_MSGHDR_MSGCTRL msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; */ return sendmsg(s->fd, &msg, 0);#else UNUSED(s); UNUSED(iov); UNUSED(count); return -1;#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -