/** Multicast a message. * * @param[in] ifaceinfo - A pointer to the SLPIfaceInfo structure that * contains information about the interfaces on which to send. * @param[in] msg - The buffer to be sent. * @param[out] socks - The address of storage for the sockets that were used * to multicast. * @param[in] dst - The target address, if using ipv6; can be null for IPv4. * * @return Zero on sucess, or a non-zero value, with errno set on error. * * @remarks May be used to receive responses. Must be close by caller using * SLPXcastSocketsClose. */ int SLPMulticastSend(const SLPIfaceInfo * ifaceinfo, const SLPBuffer msg, SLPXcastSockets * socks, struct sockaddr_storage * dst) { int flags = 0; int xferbytes; #ifdef MSG_NOSIGNAL flags = MSG_NOSIGNAL; #endif for (socks->sock_count = 0; socks->sock_count < ifaceinfo->iface_count; socks->sock_count++) { int family = ifaceinfo->iface_addr[socks->sock_count].ss_family; socks->sock[socks->sock_count] = socket(family, SOCK_DGRAM, 0); if((socks->sock[socks->sock_count] == SLP_INVALID_SOCKET) || (SetMulticastIF(family, socks->sock[socks->sock_count], &ifaceinfo->iface_addr[socks->sock_count]) || (SetMulticastTTL(family, socks->sock[socks->sock_count], SLPPropertyAsInteger("net.slp.multicastTTL"))))) return -1; /* error creating socket or setting socket option */ SLPNetworkSetSndRcvBuf(socks->sock[socks->sock_count]); memcpy(&socks->peeraddr[socks->sock_count], dst, sizeof(struct sockaddr_storage)); xferbytes = sendto(socks->sock[socks->sock_count], (char *)msg->start, (int)(msg->end - msg->start), flags, (struct sockaddr *)&socks->peeraddr[socks->sock_count], SLPNetAddrLen(&socks->peeraddr[socks->sock_count])); if (xferbytes <= 0) return -1; /* error sending */ } return 0; }
/*==========================================================================*/ SLPDSocket* SLPDSocketCreateDatagram(struct in_addr* peeraddr, int type) /* myaddr - (IN) the address of the interface to join mcast on */ /* */ /* peeraddr - (IN) the address of the peer to connect to */ /* */ /* type (IN) DATAGRAM_UNICAST, DATAGRAM_MULTICAST, DATAGRAM_BROADCAST */ /* */ /* Returns: A datagram socket SLPDSocket->state will be set to */ /* DATAGRAM_UNICAST, DATAGRAM_MULTICAST, or DATAGRAM_BROADCAST */ /*==========================================================================*/ { SLPDSocket* sock; sock = SLPDSocketAlloc(); if(sock) { sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); if(sock->recvbuf && sock->sendbuf) { sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >=0) { switch(type) { case DATAGRAM_BROADCAST: EnableBroadcast(sock->fd); break; case DATAGRAM_MULTICAST: SetMulticastTTL(sock->fd,G_SlpdProperty.multicastTTL); break; default: break; } sock->peeraddr.sin_family = AF_INET; sock->peeraddr.sin_addr = *peeraddr; sock->peeraddr.sin_port = htons(SLP_RESERVED_PORT); sock->state = type; } else { SLPDSocketFree(sock); sock = 0; } } else { SLPDSocketFree(sock); sock = 0; } } return sock; }
int RTPConnection::Create(int pbase,unsigned long localipaddress) { int size; RTPSOCKLENTYPE socklen; if (socketsopened) return ERR_RTP_CONNALREADYCREATED; /* Check if the localportbase is even, conforming to RFC 1889 */ if (pbase%2 != 0) return ERR_RTP_PORTBASENOTEVEN; /* Create the sockets */ rtpsock = socket(AF_INET,SOCK_DGRAM,0); if (rtpsock == RTPSOCKERR) return ERR_RTP_CANTCREATESOCKET; rtcpsock = socket(AF_INET,SOCK_DGRAM,0); if (rtcpsock == RTPSOCKERR) return ERR_RTP_CANTCREATESOCKET; sendsock = socket(AF_INET,SOCK_DGRAM,0); if (sendsock == RTPSOCKERR) return ERR_RTP_CANTCREATESOCKET; /* Set socket receive and send buffers */ size = RTP_RECEIVEBUFFERSIZE; if (setsockopt(rtpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0) return ERR_RTP_CANTSETSOCKETBUFFER; size = RTP_RECEIVEBUFFERSIZE; if (setsockopt(rtcpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0) return ERR_RTP_CANTSETSOCKETBUFFER; size = RTP_SENDBUFFERSIZE; if (setsockopt(sendsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0) return ERR_RTP_CANTSETSOCKETBUFFER; /* Bind the sockets */ struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(0); addr.sin_addr.s_addr = htonl(0); if (bind(sendsock,(struct sockaddr *)&addr,sizeof(struct sockaddr)) != 0) { RTPCLOSESOCKET(rtpsock); RTPCLOSESOCKET(rtcpsock); RTPCLOSESOCKET(sendsock); return ERR_RTP_CANTBINDSOCKET; } addr.sin_family = AF_INET; addr.sin_port = htons(pbase); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(rtpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr)) != 0) { RTPCLOSESOCKET(rtpsock); RTPCLOSESOCKET(rtcpsock); RTPCLOSESOCKET(sendsock); return ERR_RTP_CANTBINDSOCKET; } addr.sin_family = AF_INET; addr.sin_port = htons(pbase+1); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(rtcpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr)) != 0) { RTPCLOSESOCKET(rtpsock); RTPCLOSESOCKET(rtcpsock); RTPCLOSESOCKET(sendsock); return ERR_RTP_CANTBINDSOCKET; } /* Get the port number of the send socket */ socklen = sizeof(struct sockaddr_in); if (getsockname(sendsock,(struct sockaddr *)&addr,&socklen) != 0) { RTPCLOSESOCKET(rtpsock); RTPCLOSESOCKET(rtcpsock); RTPCLOSESOCKET(sendsock); return ERR_RTP_CANTGETSOCKETPORT; } sendport = ntohs(addr.sin_port); /* Get the local IP address */ if (localipaddress == 0) // user didn't supply an IP address { localip = CalcLocalIP(); if (localip == 0) { RTPCLOSESOCKET(rtpsock); RTPCLOSESOCKET(rtcpsock); RTPCLOSESOCKET(sendsock); return ERR_RTP_CANTGETLOCALIP; } } else // user specified the local IP address localip = localipaddress; socketsopened = true; #ifdef RTP_MULTICAST if (SetMulticastTTL(RTP_DEFAULTMULTICAST_TTL) < 0) { socketsopened = false; RTPCLOSESOCKET(rtpsock); RTPCLOSESOCKET(rtcpsock); RTPCLOSESOCKET(sendsock); return ERR_RTP_CANTSETMULTICASTTTL; } #endif // RTP_MULTICAST portbase = pbase; return 0; }