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

📄 slpd_incoming.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*                                                                         *//* Project:     OpenSLP - OpenSource implementation of Service Location    *//*              Protocol Version 2                                         *//*                                                                         *//* File:        slpd_incoming.c                                            *//*                                                                         *//* Abstract:    Handles "incoming" network conversations requests made by  *//*              other agents to slpd. (slpd_outgoing.c handles reqests     *//*              made by slpd to other agents)                              *//*                                                                         *//*-------------------------------------------------------------------------*//*                                                                         *//*     Please submit patches to http://www.openslp.org                     *//*                                                                         *//*-------------------------------------------------------------------------*//*                                                                         *//* Copyright (C) 2000 Caldera Systems, Inc                                 *//* All rights reserved.                                                    *//*                                                                         *//* Redistribution and use in source and binary forms, with or without      *//* modification, are permitted provided that the following conditions are  *//* met:                                                                    */ /*                                                                         *//*      Redistributions of source code must retain the above copyright     *//*      notice, this list of conditions and the following disclaimer.      *//*                                                                         *//*      Redistributions in binary form must reproduce the above copyright  *//*      notice, this list of conditions and the following disclaimer in    *//*      the documentation and/or other materials provided with the         *//*      distribution.                                                      *//*                                                                         *//*      Neither the name of Caldera Systems nor the names of its           *//*      contributors may be used to endorse or promote products derived    *//*      from this software without specific prior written permission.      *//*                                                                         *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    *//*                                                                         *//***************************************************************************//*=========================================================================*//* slpd includes                                                           *//*=========================================================================*/#include "slpd_incoming.h"#include "slpd_socket.h"#include "slpd_process.h"#include "slpd_property.h"#include "slpd_log.h"/*=========================================================================*//* common code includes                                                    *//*=========================================================================*/#include "slp_xmalloc.h"#include "slp_message.h"/*=========================================================================*/SLPList G_IncomingSocketList = {0,0,0};/*=========================================================================*//*-------------------------------------------------------------------------*/void IncomingDatagramRead(SLPList* socklist, SLPDSocket* sock)/*-------------------------------------------------------------------------*/{    int                 bytesread;    int                 bytestowrite;    int                 byteswritten;    int                 peeraddrlen = sizeof(struct sockaddr_in);    bytesread = recvfrom(sock->fd,                         sock->recvbuf->start,                         SLP_MAX_DATAGRAM_SIZE,                         0,                         (struct sockaddr *) &(sock->peeraddr),                         &peeraddrlen);    if (bytesread > 0)    {        sock->recvbuf->end = sock->recvbuf->start + bytesread;        switch (SLPDProcessMessage(&sock->peeraddr,                                   sock->recvbuf,                                   &(sock->sendbuf)))        {        case SLP_ERROR_PARSE_ERROR:        case SLP_ERROR_VER_NOT_SUPPORTED:        case SLP_ERROR_MESSAGE_NOT_SUPPORTED:            break;                            default:            /* check to see if we should send anything */            bytestowrite = sock->sendbuf->end - sock->sendbuf->start;            if (bytestowrite > 0)            {                byteswritten = sendto(sock->fd,                                       sock->sendbuf->start,                                      bytestowrite,                                      0,                                      (struct sockaddr *)&(sock->peeraddr),                                      sizeof(struct sockaddr_in));                if (byteswritten != bytestowrite)                {                    SLPDLog("NETWORK_ERROR - %d replying %s\n",                            errno,                            inet_ntoa(sock->peeraddr.sin_addr));                }            }        }    }}/*-------------------------------------------------------------------------*/void IncomingStreamWrite(SLPList* socklist, SLPDSocket* sock)/*-------------------------------------------------------------------------*/{    int byteswritten, flags = 0;#if defined(MSG_DONTWAIT)    flags = MSG_DONTWAIT;#endif    if (sock->state == STREAM_WRITE_FIRST)    {        /* make sure that the start and curpos pointers are the same */        sock->sendbuf->curpos = sock->sendbuf->start;        sock->state = STREAM_WRITE;    }    if (sock->sendbuf->end - sock->sendbuf->start != 0)    {        byteswritten = send(sock->fd,                            sock->sendbuf->curpos,                            sock->sendbuf->end - sock->sendbuf->start,                            flags);        if (byteswritten > 0)        {            /* reset lifetime to max because of activity */            sock->age = 0;            sock->sendbuf->curpos += byteswritten;            if (sock->sendbuf->curpos == sock->sendbuf->end)            {                /* message is completely sent */                sock->state = STREAM_READ_FIRST;            }        }        else        {#ifdef _WIN32            if (WSAEWOULDBLOCK == WSAGetLastError())#else            if (errno == EWOULDBLOCK)#endif            {                /* Error occured or connection was closed */                sock->state = SOCKET_CLOSE;            }        }        }}/*-------------------------------------------------------------------------*/void IncomingStreamRead(SLPList* socklist, SLPDSocket* sock)/*-------------------------------------------------------------------------*/{    int     bytesread, recvlen = 0;    char    peek[16];    int     peeraddrlen = sizeof(struct sockaddr_in);    if (sock->state == STREAM_READ_FIRST)    {        /*---------------------------------------------------*/        /* take a peek at the packet to get size information */        /*---------------------------------------------------*/        bytesread = recvfrom(sock->fd,                             peek,                             16,                             MSG_PEEK,                             (struct sockaddr *)&(sock->peeraddr),                             &peeraddrlen);        if (bytesread > 0 && bytesread >= (*peek == 2 ? 5 : 4))        {            if (*peek == 2)                recvlen = AsUINT24(peek + 2);            else if (*peek == 1) /* SLPv1 packet */                recvlen = AsUINT16(peek + 2);            /* one byte is minimum */            if (recvlen <= 0)                recvlen = 1;            /* allocate the recvbuf big enough for the whole message */            sock->recvbuf = SLPBufferRealloc(sock->recvbuf,recvlen);            if (sock->recvbuf)            {                sock->state = STREAM_READ;             }            else            {                SLPDLog("INTERNAL_ERROR - out of memory!\n");                sock->state = SOCKET_CLOSE;            }        }        else        {            sock->state = SOCKET_CLOSE;            return;        }            }    if (sock->state == STREAM_READ)    {        /*------------------------------*/        /* recv the rest of the message */        /*------------------------------*/        bytesread = recv(sock->fd,                         sock->recvbuf->curpos,                         sock->recvbuf->end - sock->recvbuf->curpos,                         0);                      if (bytesread > 0)        {            /* reset age to max because of activity */            sock->age = 0;            sock->recvbuf->curpos += bytesread;            if (sock->recvbuf->curpos == sock->recvbuf->end)            {                switch (SLPDProcessMessage(&sock->peeraddr,                                           sock->recvbuf,                                           &(sock->sendbuf)))                {                case SLP_ERROR_PARSE_ERROR:                case SLP_ERROR_VER_NOT_SUPPORTED:                case SLP_ERROR_MESSAGE_NOT_SUPPORTED:                    sock->state = SOCKET_CLOSE;                    break;                                    default:                    sock->state = STREAM_WRITE_FIRST;                    IncomingStreamWrite(socklist, sock);                }            }        }        else        {            /* error in recv() or eof */            sock->state = SOCKET_CLOSE;        }    }}/*-------------------------------------------------------------------------*/void IncomingSocketListen(SLPList* socklist, SLPDSocket* sock)/*-------------------------------------------------------------------------*/{    int                 fdflags;    sockfd_t            fd;    SLPDSocket*         connsock;    struct sockaddr_in  peeraddr;    socklen_t           peeraddrlen;#ifdef _WIN32    const char   lowat = SLPD_SMALLEST_MESSAGE;#else        const int   lowat = SLPD_SMALLEST_MESSAGE;#endif    /* Only accept if we can. If we still maximum number of sockets, just*/    /* ignore the connection */    if (socklist->count < SLPD_MAX_SOCKETS)    {        peeraddrlen = sizeof(peeraddr);        fd = accept(sock->fd,                    (struct sockaddr *) &peeraddr,                     &peeraddrlen);        if (fd >= 0)        {            connsock = SLPDSocketAlloc();            if (connsock)            {                /* setup the accepted socket */                connsock->fd        = fd;                connsock->peeraddr  = peeraddr;                connsock->state     = STREAM_READ_FIRST;                /* Set the low water mark on the accepted socket */                setsockopt(connsock->fd,SOL_SOCKET,SO_RCVLOWAT,&lowat,sizeof(lowat));                setsockopt(connsock->fd,SOL_SOCKET,SO_SNDLOWAT,&lowat,sizeof(lowat));                 /* set accepted socket to non blocking */#ifdef _WIN32                fdflags = 1;                ioctlsocket(connsock->fd, FIONBIO, &fdflags);#else                fdflags = fcntl(connsock->fd, F_GETFL, 0);                fcntl(connsock->fd,F_SETFL, fdflags | O_NONBLOCK);#endif                        SLPListLinkHead(socklist,(SLPListItem*)connsock);            }        }    }}/*=========================================================================*/void SLPDIncomingHandler(int* fdcount,

⌨️ 快捷键说明

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