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

📄 libslp_network.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 4 页
字号:
        socktype = SOCK_DGRAM;    }    else    {        maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.unicastMaximumWait"));        SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.unicastTimeouts"),                                    timeouts,                                    MAX_RETRANSMITS );        size = sizeof(socktype);        getsockopt(sock,SOL_SOCKET,SO_TYPE,&socktype,&size);        if(socktype == SOCK_DGRAM)        {            xmitcount = 0;            looprecv  = 1;        }        else        {            xmitcount = MAX_RETRANSMITS;            looprecv  = 0;        }    }    /* 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;        looprecv = 1;    }    /*---------------------------------------------------------------------*/    /* 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.   */    /*---------------------------------------------------------------------*/    if(buftype == SLP_FUNCT_SRVRQST ||       buftype == SLP_FUNCT_ATTRRQST ||       buftype == SLP_FUNCT_SRVTYPERQST)    {        prlist = (char*)xmalloc(mtu);        if(prlist == 0)        {            result = SLP_MEMORY_ALLOC_FAILED;            goto CLEANUP;        }        *prlist = 0;        prlistlen = 0;     }    /*--------------------------*/    /* Main retransmission loop */    /*--------------------------*/    while(xmitcount <= MAX_RETRANSMITS)    {        xmitcount++;        /*--------------------*/        /* setup recv timeout */        /*--------------------*/        if(socktype == SOCK_DGRAM)        {            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;        }        else        {            timeout.tv_sec = maxwait / 1000;            timeout.tv_usec = (maxwait % 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 && socktype == SOCK_DGRAM)        {            if(xmitcount == 0)            {                result = SLP_BUFFER_OVERFLOW;            }            goto FINISHED;        }        if((sendbuf = SLPBufferRealloc(sendbuf,size)) == 0)        {            result = SLP_MEMORY_ALLOC_FAILED;            goto CLEANUP;        }        /*-----------------------------------*/        /* Add the header to the send buffer */        /*-----------------------------------*/        /*version*/        *(sendbuf->start)       = 2;        /*function id*/        *(sendbuf->start + 1)   = buftype;        /*length*/        ToUINT24(sendbuf->start + 2, size);        /*flags*/        flags = (ISMCAST(destaddr->sin_addr) ? SLP_FLAG_MCAST : 0);        if (buftype == SLP_FUNCT_SRVREG)        {            flags |= SLP_FLAG_FRESH;        }        ToUINT16(sendbuf->start + 5, flags);        /*ext offset*/        /* TRICKY: the extoffset passed into us was the offset not         * including the header.  We need to fix up the offset so         * that it is from the beginning of the SLP message         */        if(extoffset != 0)	{            ToUINT24(sendbuf->start + 7,extoffset + langtaglen + 14);	}        else        {	    ToUINT24(sendbuf->start + 7, 0);	}        /*xid*/        ToUINT16(sendbuf->start + 10,xid);        /*lang tag len*/        ToUINT16(sendbuf->start + 12,langtaglen);        /*lang tag*/        memcpy(sendbuf->start + 14, langtag, langtaglen);        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 */        /*----------------------*/        result = SLPNetworkSendMessage(sock,                                       socktype,                                       sendbuf,                                       destaddr,                                       &timeout);        if(result != 0)        {            /* we could not send the message for some reason */            /* we're done */            if(errno == ETIMEDOUT)            {                result = SLP_NETWORK_TIMED_OUT;            }            else            {                result = SLP_NETWORK_ERROR;                }            goto FINISHED;        }        /*----------------*/        /* Main recv loop */        /*----------------*/        do        {            if(SLPNetworkRecvMessage(sock,                                     socktype,                                     &recvbuf,                                     &peeraddr,                                     &timeout) != 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;                }                break;            }            else            {                /* Sneek in and check the XID */                if(AsUINT16(recvbuf->start+10) == xid)                {                    rplycount += 1;                    /* Call the callback with the result and recvbuf */                    if(callback(result,&peeraddr,recvbuf,cookie) == SLP_FALSE)                    {                        /* Caller does not want any more info */                        /* We are done!                       */                        goto CLEANUP;                    }                                        /* add the peer to the previous responder list          */                    /* Note that prlist will be NULL if message type is not */                    /* SLP_FUNCT_SRVRQST, SLP_FUNCT_ATTRRQST, or            */                    /* SLP_FUNCT_SRVTYPERQST)                               */                    if(prlist && socktype == SOCK_DGRAM)                    {                        /* calculate the peeraddr string and length */                        char* peeraddrstr = NULL;                        int peeraddrstrlen = 0;                        peeraddrstr = inet_ntoa(peeraddr.sin_addr);                        if(peeraddrstr)                        {                            peeraddrstrlen = strlen(peeraddrstr);                                                        /* Append to the prlist if we won't overflow */                            if((prlistlen + peeraddrstrlen + 1) < mtu )                            {                                /* append comma if necessary */                                if(prlistlen != 0)                                {                                    strcat(prlist,",");                                    prlistlen ++;                                }                                /* append address string */                                strcat(prlist,peeraddrstr);                                prlistlen += peeraddrstrlen;                            }                        }                    }                }            }        }while(looprecv);    }    FINISHED:        /*-----------------------------------------------*/    /* Notify the last time callback that we're done */    /*-----------------------------------------------*/    if(rplycount)    {        result = SLP_LAST_CALL;     }        if(result == SLP_NETWORK_TIMED_OUT && ISMCAST(destaddr->sin_addr))    {        result = SLP_LAST_CALL;    }    callback(result, &peeraddr, recvbuf, cookie);        if(result == SLP_LAST_CALL)    {        result = 0;    }    /*----------------*/    /* Free resources */    /*----------------*/    CLEANUP:    if(prlist) xfree(prlist);    SLPBufferFree(sendbuf);    SLPBufferFree(recvbuf);        return result;}/*=========================================================================*/ #ifndef MI_NOT_SUPPORTEDSLPError NetworkMcastRqstRply(PSLPHandleInfo handle,#elseSLPError NetworkMcastRqstRply(const char* langtag,#endif /* MI_NOT_SUPPORTED */                              char* buf,                              char buftype,                              int bufsize,                              NetworkRplyCallback callback,                              void * cookie)/* Description:                                                            *//*                                                                         *//* Broadcasts/multicasts SLP messages via multicast convergence algorithm  *//*                                                                         *//* langtag  (IN) Language tag to use in SLP message header                 *//*                                                                         *//* buf      (IN) pointer to the portion of the SLP message to send. The    *//*               portion to that should be pointed to is everything after  *//*               the pr-list. NetworkXcastRqstRply() automatically         *//*               generates the header and the prlist.                      *//*                                                                         *//* buftype  (IN) the function-id to use in the SLPMessage header           *//*                                                                         *//* bufsize  (IN) the size of the buffer pointed to by buf                  *//*                                                                         *//* callback (IN) the callback to use for reporting results                 *//*                                                                         *//* cookie   (IN) the cookie to pass to the callback                        *//*                                                                         *//* Returns  -    SLP_OK on success. SLP_ERROR on failure                   *//*=========================================================================*/ {    struct timeval      timeout;    struct sockaddr_in  peeraddr;    SLPBuffer           sendbuf         = 0;    SLPBuffer           recvbuf         = 0;

⌨️ 快捷键说明

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