slpd_outgoing.c

来自「SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.open」· C语言 代码 · 共 680 行 · 第 1/2 页

C
680
字号
        byteswritten = send(sock->fd,                            sock->sendbuf->curpos,                            sock->sendbuf->end - sock->sendbuf->start,                            flags);        if ( byteswritten > 0 )        {            /* reset age because of activity */            sock->age = 0;                         /* move buffer pointers */            sock->sendbuf->curpos += byteswritten;            /* check to see if everything was written */            if ( sock->sendbuf->curpos == sock->sendbuf->end )            {                /* Message is completely sent. Set state to read the reply */                sock->state = STREAM_READ_FIRST;            }        }        else        {#ifdef _WIN32            if ( WSAEWOULDBLOCK != WSAGetLastError() )#else            if ( errno != EWOULDBLOCK )#endif            {                /* Error occured or connection was closed. Try to reconnect */                /* Socket will be closed if connect times out               */                OutgoingStreamReconnect(socklist,sock);            }        }    }    else    {        /* nothing to write */#ifdef DEBUG        SLPDLog("yikes, an empty socket is being written!\n");#endif        sock->state = SOCKET_CLOSE;    }}/*=========================================================================*/SLPDSocket* SLPDOutgoingConnect(struct in_addr* addr)/* Get a pointer to a connected socket that is associated with the         *//* outgoing socket list.  If a connected socket already exists on the      *//* outgoing list, a pointer to it is returned, otherwise a new connection  *//* is made and added to the outgoing list                                  *//*                                                                         *//* addr (IN) the address of the peer a connection is desired for           *//*                                                                         *//* returns: pointer to socket or null on error                             *//*=========================================================================*/{    SLPDSocket* sock = (SLPDSocket*)G_OutgoingSocketList.head;    while ( sock )    {        if ( sock->state == STREAM_CONNECT_IDLE ||             sock->state > SOCKET_PENDING_IO )        {            if ( sock->peeraddr.sin_addr.s_addr == addr->s_addr )            {                break;            }        }        sock = (SLPDSocket*)sock->listitem.next;        }    if ( sock == 0 )    {        sock = SLPDSocketCreateConnected(addr);        if(sock)        {            SLPListLinkTail(&(G_OutgoingSocketList),(SLPListItem*)sock);        }    }    return sock;}/*=========================================================================*/void SLPDOutgoingDatagramWrite(SLPDSocket* sock)/* Add a ready to write outgoing datagram socket to the outgoing list.     *//* The datagram will be written then sit in the list until it ages out     *//* (after  net.slp.unicastMaximumWait)                                     *//*                                                                         *//* sock (IN) the socket that will belong on the outgoing list              *//*=========================================================================*/{    if ( sendto(sock->fd,                sock->sendbuf->start,                sock->sendbuf->end - sock->sendbuf->start,                0,                (struct sockaddr *) &(sock->peeraddr),                sizeof(struct sockaddr_in)) >= 0 )    {        /* Link the socket into the outgoing list so replies will be */        /* processed                                                 */        SLPListLinkHead(&G_OutgoingSocketList,(SLPListItem*)(sock));    }    else    {        #ifdef DEBUG        SLPDLog("ERROR: Data could not send() in SLPDOutgoingDatagramWrite()");        #endif        SLPDSocketFree(sock);    }   }/*=========================================================================*/void SLPDOutgoingHandler(int* fdcount,                         fd_set* readfds,                         fd_set* writefds)/* Handles all outgoing requests that are pending on the specified file    *//* discriptors                                                             *//*                                                                         *//* fdcount  (IN/OUT) number of file descriptors marked in fd_sets          *//*                                                                         *//* readfds  (IN) file descriptors with pending read IO                     *//*                                                                         *//* writefds  (IN) file descriptors with pending read IO                    *//*=========================================================================*/{    SLPDSocket* sock;    sock = (SLPDSocket*)G_OutgoingSocketList.head;    while ( sock && *fdcount )    {        if ( FD_ISSET(sock->fd,readfds) )        {            switch ( sock->state )            {            case DATAGRAM_MULTICAST:            case DATAGRAM_BROADCAST:            case DATAGRAM_UNICAST:                OutgoingDatagramRead(&G_OutgoingSocketList,sock);                break;            case STREAM_READ:            case STREAM_READ_FIRST:                OutgoingStreamRead(&G_OutgoingSocketList,sock);                break;            default:                /* No SOCKET_LISTEN sockets should exist */                break;            }            *fdcount = *fdcount - 1;        }        else if ( FD_ISSET(sock->fd,writefds) )        {            switch ( sock->state )            {                        case STREAM_CONNECT_BLOCK:                sock->age = 0;                sock->state = STREAM_WRITE_FIRST;            case STREAM_WRITE:            case STREAM_WRITE_FIRST:                OutgoingStreamWrite(&G_OutgoingSocketList,sock);                break;            default:                break;            }            *fdcount = *fdcount - 1;        }        sock = (SLPDSocket*)sock->listitem.next;     }                               }/*=========================================================================*/void SLPDOutgoingAge(time_t seconds)/*=========================================================================*/{    SLPDSocket* del  = 0;    SLPDSocket* sock = (SLPDSocket*)G_OutgoingSocketList.head;    while ( sock )    {        switch ( sock->state )        {        case DATAGRAM_MULTICAST:        case DATAGRAM_BROADCAST:        case DATAGRAM_UNICAST:            if ( sock->age > G_SlpdProperty.unicastMaximumWait / 1000 )            {                del = sock;            }            sock->age = sock->age + seconds;            break;        case STREAM_READ_FIRST:        case STREAM_WRITE_FIRST:            sock->age = 0;            break;                case STREAM_CONNECT_BLOCK:        case STREAM_READ:        case STREAM_WRITE:            if ( G_OutgoingSocketList.count > SLPD_COMFORT_SOCKETS )            {                /* Accelerate ageing cause we are low on sockets */                if ( sock->age > SLPD_CONFIG_BUSY_CLOSE_CONN )                {                    /* Remove peer from KnownDAs since it might be dead */                    SLPDKnownDARemove(&(sock->peeraddr.sin_addr));                    del = sock;                }            }            else            {                if ( sock->age > SLPD_CONFIG_CLOSE_CONN )                {                    /* Remove peer from KnownDAs since it might be dead */                    SLPDKnownDARemove(&(sock->peeraddr.sin_addr));                    del = sock;                }            }            sock->age = sock->age + seconds;            break;        case STREAM_CONNECT_IDLE:            if ( G_OutgoingSocketList.count > SLPD_COMFORT_SOCKETS )            {                /* Accelerate ageing cause we are low on sockets */                if ( sock->age > SLPD_CONFIG_BUSY_CLOSE_CONN )                {                    del = sock;                }            }            else            {                if ( sock->age > SLPD_CONFIG_CLOSE_CONN )                {                    del = sock;                }            }            sock->age = sock->age + seconds;            break;        case STREAM_WRITE_WAIT:            /* this when we are talking to a busy DA */            sock->age = 0;            sock->state = STREAM_WRITE_FIRST;            break;        default:            /* don't age the other sockets at all */            break;        }        sock = (SLPDSocket*)sock->listitem.next;        if ( del )        {            SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_OutgoingSocketList,(SLPListItem*)del));            del = 0;        }    }                                                 }/*=========================================================================*/int SLPDOutgoingInit()/* Initialize outgoing socket list to have appropriate sockets for all     *//* network interfaces                                                      *//*                                                                         *//* list     (IN/OUT) pointer to a socket list to be filled with sockets    *//*                                                                         *//* Returns  Zero on success non-zero on error                              *//*=========================================================================*/{    /*------------------------------------------------------------*/    /* First, remove all of the sockets that might be in the list */    /*------------------------------------------------------------*/    while ( G_OutgoingSocketList.count )    {        SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_OutgoingSocketList,(SLPListItem*)G_OutgoingSocketList.head));    }    return 0;}/*=========================================================================*/int SLPDOutgoingDeinit(int graceful)/* Deinitialize incoming socket list to have appropriate sockets for all   *//* network interfaces                                                      *//*                                                                         *//* graceful (IN) Do not close sockets with pending writes                  *//*                                                                         *//* Returns  Zero on success non-zero when pending writes remain            *//*=========================================================================*/{    SLPDSocket* del  = 0;    SLPDSocket* sock = (SLPDSocket*)G_OutgoingSocketList.head;    while ( sock )    {        /* graceful only closes sockets without pending I/O */        if ( graceful == 0 )        {            del = sock;        }        else if ( sock->state < SOCKET_PENDING_IO )        {            del = sock;        }        sock = (SLPDSocket*)sock->listitem.next;        if ( del )        {            SLPDSocketFree((SLPDSocket*)SLPListUnlink(&G_OutgoingSocketList,(SLPListItem*)del));            del = 0;        }    }    return G_OutgoingSocketList.count;}#ifdef DEBUG/*=========================================================================*/void SLPDOutgoingSocketDump()/*=========================================================================*/{}#endif

⌨️ 快捷键说明

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