⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libslp_network.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 4 页
字号:
    SLPError            result          = 0;    int                 langtaglen      = 0;    int                 prlistlen       = 0;    char*               prlist          = 0;    int                 xid             = 0;    int                 mtu             = 0;    int                 size            = 0;    int                 xmitcount       = 0;    int                 rplycount       = 0;    int                 maxwait         = 0;    int                 totaltimeout    = 0;    int                 usebroadcast    = 0;    int                 timeouts[MAX_RETRANSMITS];    SLPIfaceInfo        ifaceinfo;    SLPXcastSockets     xcastsocks;#ifdef DEBUG    /* This function only supports multicast or broadcast of the following     *  messages     */    if(buftype != SLP_FUNCT_SRVRQST &&       buftype != SLP_FUNCT_ATTRRQST &&       buftype != SLP_FUNCT_SRVTYPERQST &&       buftype != SLP_FUNCT_DASRVRQST)    {        return SLP_PARAMETER_BAD;    }#endif    /*----------------------------------------------------*/    /* Save off a few things we don't want to recalculate */    /*----------------------------------------------------*/#ifndef MI_NOT_SUPPORTED    langtaglen = strlen(handle->langtag);#else    langtaglen = strlen(langtag);#endif /* MI_NOT_SUPPORTED */    xid = SLPXidGenerate();    mtu = SLPPropertyAsInteger(SLPGetProperty("net.slp.MTU"));    sendbuf = SLPBufferAlloc(mtu);    if(sendbuf == 0)    {        result = SLP_MEMORY_ALLOC_FAILED;        goto FINISHED;    }    #ifndef MI_NOT_SUPPORTED    if(handle->McastIFList != NULL)     {        #ifdef DEBUG        fprintf(stderr, "McastIFList = %s\n", handle->McastIFList);        #endif        SLPIfaceGetInfo(handle->McastIFList, &ifaceinfo);    }    else    #endif /* MI_NOT_SUPPORTED */    if(SLPIfaceGetInfo(SLPGetProperty("net.slp.interfaces"),&ifaceinfo))    {        result = SLP_NETWORK_ERROR;        goto FINISHED;    }    usebroadcast = SLPPropertyAsBoolean(SLPGetProperty("net.slp.useBroadcast"));    /*-----------------------------------*/    /* Multicast/broadcast wait timeouts */    /*-----------------------------------*/    maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.multicastMaximumWait"));    SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.multicastTimeouts"),                                timeouts,                                MAX_RETRANSMITS );    /* Special case for fake SLP_FUNCT_DASRVRQST */    if(buftype == SLP_FUNCT_DASRVRQST)    {        /* do something special for SRVRQST that will be discovering DAs */        maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.DADiscoveryMaximumWait"));        SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.DADiscoveryTimeouts"),                                   timeouts,                                   MAX_RETRANSMITS );        /* SLP_FUNCT_DASRVRQST is a fake function.  We really want to */        /* send a SRVRQST                                             */        buftype  = SLP_FUNCT_SRVRQST;    }    /*---------------------------------------------------------------------*/    /* Allocate memory for the prlist for appropriate messages.            */    /* Notice that the prlist is as large as the MTU -- thus assuring that */    /* there will not be any buffer overwrites regardless of how many      */    /* previous responders there are.   This is because the retransmit     */    /* code terminates if ever MTU is exceeded for any datagram message.   */    /*---------------------------------------------------------------------*/    prlist = (char*)xmalloc(mtu);    if(prlist == 0)    {        result = SLP_MEMORY_ALLOC_FAILED;        goto FINISHED;    }    *prlist = 0;    prlistlen = 0;     /*--------------------------*/    /* Main retransmission loop */    /*--------------------------*/    xmitcount = 0;    while(xmitcount <= MAX_RETRANSMITS)    {        xmitcount++;        totaltimeout += timeouts[xmitcount];        if(totaltimeout >= maxwait ||  timeouts[xmitcount] == 0)        {            /* we are all done */            break;        }        timeout.tv_sec = timeouts[xmitcount] / 1000;        timeout.tv_usec = (timeouts[xmitcount] % 1000) * 1000;                /*------------------------------------------------------------------*/        /* re-allocate buffer and make sure that the send buffer does not   */        /* exceed MTU for datagram transmission                             */        /*------------------------------------------------------------------*/        size = 14 + langtaglen + bufsize;        if(buftype == SLP_FUNCT_SRVRQST ||           buftype == SLP_FUNCT_ATTRRQST ||           buftype == SLP_FUNCT_SRVTYPERQST)        {            /* add in room for the prlist */            size += 2 + prlistlen;        }        if(size > mtu)        {            if(xmitcount == 0)            {                result = SLP_BUFFER_OVERFLOW;            }            goto FINISHED;        }        if((sendbuf = SLPBufferRealloc(sendbuf,size)) == 0)        {            result = SLP_MEMORY_ALLOC_FAILED;            goto FINISHED;        }        /*-----------------------------------*/        /* Add the header to the send buffer */        /*-----------------------------------*/        /*version*/        *(sendbuf->start)       = 2;        /*function id*/        *(sendbuf->start + 1)   = buftype;        /*length*/        ToUINT24(sendbuf->start + 2, size);        /*flags*/        ToUINT16(sendbuf->start + 5, SLP_FLAG_MCAST);        /*ext offset*/        ToUINT24(sendbuf->start + 7,0);        /*xid*/        ToUINT16(sendbuf->start + 10,xid);        /*lang tag len*/        ToUINT16(sendbuf->start + 12,langtaglen);        /*lang tag*/#ifndef MI_NOT_SUPPORTED        memcpy(sendbuf->start + 14, handle->langtag, langtaglen);#else        memcpy(sendbuf->start + 14, langtag, langtaglen);#endif /* MI_NOT_SUPPORTED */        sendbuf->curpos = sendbuf->start + langtaglen + 14 ;        /*-----------------------------------*/        /* Add the prlist to the send buffer */        /*-----------------------------------*/        if(prlist)        {            ToUINT16(sendbuf->curpos,prlistlen);            sendbuf->curpos = sendbuf->curpos + 2;            memcpy(sendbuf->curpos, prlist, prlistlen);            sendbuf->curpos = sendbuf->curpos + prlistlen;        }        /*-----------------------------*/        /* Add the rest of the message */        /*-----------------------------*/        memcpy(sendbuf->curpos, buf, bufsize);        /*----------------------*/        /* send the send buffer */        /*----------------------*/        if(usebroadcast)        {            result = SLPBroadcastSend(&ifaceinfo,sendbuf,&xcastsocks);        }        else        {            result = SLPMulticastSend(&ifaceinfo,sendbuf,&xcastsocks);        }        if(result != 0)        {            /* we could not send the message for some reason */            result = SLP_NETWORK_ERROR;                goto FINISHED;        }        /*----------------*/        /* Main recv loop */        /*----------------*/        while(1)        {            #ifndef UNICAST_NOT_SUPPORTED            int retval = 0;	    if((retval = SLPXcastRecvMessage(&xcastsocks,                                   &recvbuf,                                   &peeraddr,                                   &timeout)) != 0)            #else				    if(SLPXcastRecvMessage(&xcastsocks,                                   &recvbuf,                                   &peeraddr,                                   &timeout) != 0)            #endif            {                /* An error occured while receiving the message        */                /* probably a just time out error. break for re-send.  */                if(errno == ETIMEDOUT)                {                    result = SLP_NETWORK_TIMED_OUT;                }                else                {                    result = SLP_NETWORK_ERROR;                }#ifndef UNICAST_NOT_SUPPORTED                /* retval = SLP_RETRY_UNICAST signifies that we received a		 * multicast packet of size > MTU and hence we are now sending		 * a unicast request to this IP-address		 */		if ( retval == SLP_RETRY_UNICAST ) 		{		    int tcpsockfd, retval1, retval2, unicastwait = 0;		    unicastwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.unicastMaximumWait"));		    timeout.tv_sec = unicastwait / 1000;		    timeout.tv_usec = (unicastwait % 1000) * 1000;				    tcpsockfd = SLPNetworkConnectStream(&peeraddr, &timeout);		    if ( tcpsockfd >= 0 ) 		    {		        ToUINT16(sendbuf->start + 5, SLP_FLAG_UCAST);			xid = SLPXidGenerate();			ToUINT16(sendbuf->start + 10,xid);			   			 retval1 = SLPNetworkSendMessage(tcpsockfd, SOCK_STREAM, sendbuf, &peeraddr, &timeout);			 if ( retval1 != 0 ) 			 {			     /* we could not send the message for some reason */			     /* we close the TCP connection and break */			     if(errno == ETIMEDOUT) 			     {			         result = SLP_NETWORK_TIMED_OUT;			     } 			     else 			     {			         result = SLP_NETWORK_ERROR;			     }#ifdef _WIN32	                closesocket(tcpsockfd);#else			     close(tcpsockfd);		    #endif                             			     break;			 }			                             retval2 = SLPNetworkRecvMessage(tcpsockfd, SOCK_STREAM, &recvbuf, &peeraddr, &timeout);                         if ( retval2 != 0 ) 			 {			     /* An error occured while receiving the message */			     /* probably a just time out error. break for re-send.  */			     if(errno == ETIMEDOUT) 			     {			         result = SLP_NETWORK_TIMED_OUT;			     } 			     else 			     {				 result = SLP_NETWORK_ERROR;			     }			#ifdef _WIN32	                closesocket(tcpsockfd);#else			     close(tcpsockfd);#endif			     break;			 }			 #ifdef _WIN32	            closesocket(tcpsockfd);#else			 close(tcpsockfd);#endif			 result = SLP_OK;			 goto SNEEK;			                        		    } 		    else 		    {			/* Unsuccessful in opening a TCP connection */			/* just break and retry everything */			break;			                       		    }               		}		else		{#endif                   break;#ifndef UNICAST_NOT_SUPPORTED		}#endif	     }#ifndef UNICAST_NOT_SUPPORTED            SNEEK:#endif            /* Sneek in and check the XID */            if(AsUINT16(recvbuf->start+10) == xid)            {                rplycount += 1;                /* Call the callback with the result and recvbuf */#ifndef MI_NOT_SUPPORTED                if (cookie == NULL)                {                     cookie = (PSLPHandleInfo)handle;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -