예제 #1
0
파일: slp_xcast.c 프로젝트: ncultra/openslp
/** 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;
}
예제 #2
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;
}