Beispiel #1
0
/*-------------------------------------------------------------------------*/
int v1ProcessSrvRqst(struct sockaddr_in* peeraddr,
                     SLPMessage message,
                     SLPBuffer* sendbuf,
                     int errorcode)
/*-------------------------------------------------------------------------*/
{
    int                         i;
    int                         urllen;
    int                         size        = 0;
    SLPDDatabaseSrvRqstResult*  db          = 0;
    SLPBuffer                   result      = *sendbuf;

    /*--------------------------------------------------------------*/
    /* If errorcode is set, we can not be sure that message is good */
    /* Go directly to send response code                            */
    /*--------------------------------------------------------------*/
    if (errorcode)
    {
        goto RESPOND;
    }

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if (SLPIntersectStringList(message->body.srvrqst.prlistlen,
                               message->body.srvrqst.prlist,
                               G_SlpdProperty.interfacesLen,
                               G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------------------*/
    /* Check to to see if a this is a special SrvRqst */
    /*------------------------------------------------*/
    if (SLPCompareString(message->body.srvrqst.srvtypelen,
                         message->body.srvrqst.srvtype,
                         15,
                         "directory-agent") == 0)
    {
        errorcode = v1ProcessDASrvRqst(peeraddr, message, sendbuf, errorcode);
        return errorcode;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if (SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                               message->body.srvrqst.scopelist,
                               G_SlpdProperty.useScopesLen,
                               G_SlpdProperty.useScopes) != 0)
    {
        /*-------------------------------*/
        /* Find services in the database */
        /*-------------------------------*/
        errorcode = SLPDDatabaseSrvRqstStart(message, &db);
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }


    RESPOND:
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if (message->header.flags & SLP_FLAG_MCAST)
    {
        if (errorcode != 0 || db->urlcount == 0)
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }

    /*-------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvrply */
    /*-------------------------------------------------------------*/
    size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes
          for url count */
    if (errorcode == 0)
    {
        for (i = 0; i < db->urlcount; i++)
        {
            urllen = INT_MAX;
            errorcode = SLPv1ToEncoding(0, 
                                        &urllen,
                                        message->header.encoding,  
                                        db->urlarray[i]->url,
                                        db->urlarray[i]->urllen);
            if (errorcode)
                break;
            size += urllen + 4; /* 2 bytes for lifetime, 2 bytes for urllen */
        } 
        result = SLPBufferRealloc(result,size);
        if (result == 0)
        {
            errorcode = SLP_ERROR_INTERNAL_ERROR;
        }
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
    /*length*/
    ToUINT16(result->start + 2, size);
    /*flags - TODO set the flags correctly */
    *(result->start + 4) = message->header.flags |
                           (size > SLP_MAX_DATAGRAM_SIZE ? SLPv1_FLAG_OVERFLOW : 0);  
    /*dialect*/
    *(result->start + 5) = 0;
    /*language code*/
    memcpy(result->start + 6, message->header.langtag, 2);
    ToUINT16(result->start + 8, message->header.encoding);
    /*xid*/
    ToUINT16(result->start + 10, message->header.xid);

    /*-------------------------*/
    /* Add rest of the SrvRply */
    /*-------------------------*/
    result->curpos = result->start + 12;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    if (errorcode == 0)
    {
        /* urlentry count */
        ToUINT16(result->curpos, db->urlcount);
        result->curpos = result->curpos + 2;
        for (i = 0; i < db->urlcount; i++)
        {
            /* url-entry lifetime */
            ToUINT16(result->curpos, db->urlarray[i]->lifetime);
            result->curpos = result->curpos + 2;
            /* url-entry url and urllen */
            urllen = size;      
            errorcode = SLPv1ToEncoding(result->curpos + 2, 
                                        &urllen,
                                        message->header.encoding,  
                                        db->urlarray[i]->url,
                                        db->urlarray[i]->urllen);
            ToUINT16(result->curpos, urllen);
            result->curpos = result->curpos + 2 + urllen;
        }
    }
    else
    {
        /* urlentry count */
        ToUINT16(result->curpos, 0);
        result->curpos = result->curpos + 2;
    }

    FINISHED:   

    SLPDDatabaseSrvRqstEnd(db);

    *sendbuf = result;

    return errorcode;
}
Beispiel #2
0
/** Read data from an outbound stream-oriented connection.
 *
 * @param[in] socklist - The list of sockets being monitored.
 * @param[in] sock - The socket to be read from.
 */
void OutgoingStreamRead(SLPList * socklist, SLPDSocket * sock)
{
   int bytesread;
   char peek[16];
   socklen_t peeraddrlen = sizeof(struct sockaddr_storage);
   unsigned int msglen;

   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)
      {
         /* allocate the recvbuf big enough for the whole message */
         msglen = PEEK_LENGTH(peek);

         sock->recvbuf = SLPBufferRealloc(sock->recvbuf, msglen);
         if (sock->recvbuf)
            sock->state = STREAM_READ;
         else
         {
            SLPDLog("INTERNAL_ERROR - out of memory!\n");
            sock->state = SOCKET_CLOSE;
         }
      }
      else if (bytesread == -1)
      {
#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
      {
         sock->state = SOCKET_CLOSE;
      }
   }

   if (sock->state == STREAM_READ)
   {
      /*------------------------------*/
      /* recv the rest of the message */
      /*------------------------------*/
      bytesread = recv(sock->fd, (char *)sock->recvbuf->curpos,
            (int)(sock->recvbuf->end - sock->recvbuf->curpos), 0);
      if (bytesread > 0)
      {
         /* reset age because of activity */
         sock->age = 0;

         /* move buffer pointers */
         sock->recvbuf->curpos += bytesread;

         /* check to see if everything was read */
         if (sock->recvbuf->curpos == sock->recvbuf->end)
            switch (SLPDProcessMessage(&(sock->peeraddr), &(sock->localaddr),
                        sock->recvbuf, &(sock->sendbuf), 0))
            {
               case SLP_ERROR_DA_BUSY_NOW:
                  sock->state = STREAM_WRITE_WAIT;
                  break;
               case SLP_ERROR_PARSE_ERROR:
               case SLP_ERROR_VER_NOT_SUPPORTED:
                  sock->state = SOCKET_CLOSE;
                  break;
               default:
                  /* End of outgoing message exchange. Unlink   */
                  /* send buf from to do list and free it       */
                  SLPBufferFree(sock->sendbuf);
                  sock->sendbuf = NULL;
                  sock->state = STREAM_WRITE_FIRST;
                  /* clear the reconnection count since we actually
                   * transmitted a successful message exchange
                   */
                  sock->reconns = 0;
                  break;
            }
      }
      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);
         }
      }
   }
}
Beispiel #3
0
/*-------------------------------------------------------------------------*/
void HandleStreamRead(SLPDSocketList* list, SLPDSocket* sock)
/*-------------------------------------------------------------------------*/
{
    int     fdflags;
    int     bytesread;
    char    peek[16];
    
    if(sock->state == STREAM_FIRST_READ)
    {
        fdflags = fcntl(sock->fd, F_GETFL, 0);
        fcntl(sock->fd,F_SETFL, fdflags | O_NONBLOCK);
        
        /*---------------------------------------------------------------*/
        /* take a peek at the packet to get version and size information */
        /*---------------------------------------------------------------*/
        bytesread = recvfrom(sock->fd,
                             peek,
                             16,
                             MSG_PEEK,
                             &(sock->peerinfo.peeraddr),
                             &(sock->peerinfo.peeraddrlen));
        if(bytesread > 0)
        {
            /* check the version */
            if(*peek == 2)
            {
                /* allocate the recvbuf big enough for the whole message */
                sock->recvbuf = SLPBufferRealloc(sock->recvbuf,AsUINT24(peek+2));
                if(sock->recvbuf)
                {
                    sock->state = STREAM_READ;
                }
                else
                {
                    SLPLog("Slpd is out of memory!\n");
                    sock->state = SOCKET_CLOSE;
                }
            }
            else
            {
                SLPLog("Unsupported version %i received from %s\n",
                       *peek,
                       inet_ntoa(sock->peerinfo.peeraddr.sin_addr));

                sock->state = SOCKET_CLOSE;
            }
        }
        else
        {
            if(errno != EWOULDBLOCK)
            {
                sock->state = SOCKET_CLOSE;
                return;
            }
        }        

        
        /*------------------------------*/
        /* recv the rest of the message */
        /*------------------------------*/
        bytesread = recv(sock->fd,
                         sock->recvbuf->curpos,
                         sock->recvbuf->end - sock->recvbuf->curpos,
                         0);              

        if(bytesread > 0)
        {
            /*------------------------------*/
            /* Reset the timestamp          */
            /*------------------------------*/
            time(&(sock->timestamp));
            
            sock->recvbuf->curpos += bytesread;
            if(sock->recvbuf->curpos == sock->recvbuf->end)
            {
                if(SLPDProcessMessage(&sock->peerinfo,
                                      sock->recvbuf,
                                      sock->sendbuf) == 0)
                {
                    sock->state = STREAM_FIRST_WRITE;
                }
                else
                {
                    /* An error has occured in SLPDProcessMessage() */
                    SLPLog("An error while processing message from %s\n",
                           inet_ntoa(sock->peerinfo.peeraddr.sin_addr));
                    sock->state = SOCKET_CLOSE;
                }                                                          
            }
        }
        else
        {
            if(errno != EWOULDBLOCK)
            {
                /* error in recv() */
                sock->state = SOCKET_CLOSE;
            }
        }
    }
}
Beispiel #4
0
/*-------------------------------------------------------------------------*/
int ProcessSrvReg(struct sockaddr_in* peeraddr,
                  SLPMessage message,
                  SLPBuffer* sendbuf,
                  int errorcode)
/*                                                                         */
/* Returns: non-zero if message should be silently dropped                 */
/*-------------------------------------------------------------------------*/
{
    unsigned int    regtype;
    SLPBuffer       result  = *sendbuf;

    /*--------------------------------------------------------------*/
    /* If errorcode is set, we can not be sure that message is good */
    /* Go directly to send response code  also do not process mcast */
    /* srvreg or srvdereg messages                                  */
    /*--------------------------------------------------------------*/
    if(errorcode || message->header.flags & SLP_FLAG_MCAST)
    {
        goto RESPOND;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if(SLPIntersectStringList(message->body.srvreg.scopelistlen,
                              message->body.srvreg.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes))
    {

        /*-------------------------------*/
        /* TODO: Validate the authblocks */
        /*-------------------------------*/


        /*---------------------------------*/
        /* put the service in the database */
        /*---------------------------------*/
        regtype = 0;
        if(message->header.flags & SLP_FLAG_FRESH)
        {
            regtype |= SLPDDATABASE_REG_FRESH;
        }
        if(ISLOCAL(peeraddr->sin_addr))
        {
            regtype |= SLPDDATABASE_REG_LOCAL;
        }
        errorcode = SLPDDatabaseReg(&(message->body.srvreg),regtype);
        if(errorcode > 0)
        {
            errorcode = SLP_ERROR_INVALID_REGISTRATION;
        }
        else if(errorcode < 0)
        {
            errorcode = SLP_ERROR_INTERNAL_ERROR;
        }
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    RESPOND:    
    /*--------------------------------------------------------------------*/
    /* don't send back reply anything multicast SrvReg (set result empty) */
    /*--------------------------------------------------------------------*/
    if(message->header.flags & SLP_FLAG_MCAST ||
       ISMCAST(peeraddr->sin_addr))
    {
        result->end = result->start;
        goto FINISHED;
    }


    /*------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvack */
    /*------------------------------------------------------------*/
    result = SLPBufferRealloc(result,message->header.langtaglen + 16);
    if(result == 0)
    {
        errorcode = SLP_ERROR_INTERNAL_ERROR;
        goto FINISHED;
    }


    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVACK;
    /*length*/
    ToUINT24(result->start + 2,message->header.langtaglen + 16);
    /*flags*/
    ToUINT16(result->start + 5,0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);

    /*-------------------*/
    /* Add the errorcode */
    /*-------------------*/
    ToUINT16(result->start + 14 + message->header.langtaglen, errorcode);

    FINISHED:
    *sendbuf = result;
    return errorcode;
}
Beispiel #5
0
/*-------------------------------------------------------------------------*/
void ProcessSrvReg(SLPDPeerInfo* peerinfo,
                   SLPMessage message,
                   SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int errorcode;

    if(message->header.flags & SLP_FLAG_MCAST)
    {
        /* don't do anything multicast SrvReg (set result empty) */
        result->end = result->start;
        return;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if(SLPIntersectStringList(message->body.srvreg.scopelistlen,
                              message->body.srvreg.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes))
    {
        /*-------------------------------*/
        /* TODO: Validate the authblocks */
        /*-------------------------------*/
    
    
        /*---------------------------------*/
        /* put the service in the database */
        /*---------------------------------*/
#ifdef WIN32
      if(SLPDDatabaseReg(&(message->body.srvreg),
                           message->header.flags | SLP_FLAG_FRESH,
                           GetCurrentProcessId(),
                           0) == 0) /* TODO: Find an equivalent to 
                                       user id on Win32*/
#else
      if(SLPDDatabaseReg(&(message->body.srvreg),
                           message->header.flags | SLP_FLAG_FRESH,
                           getpid(),
                           getuid()) == 0)
#endif
        {
            errorcode = 0;
        }
        else
        {
            errorcode = SLP_ERROR_INTERNAL_ERROR;
        }    
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    /*------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvack */
    /*------------------------------------------------------------*/
    result = SLPBufferRealloc(result,message->header.langtaglen + 16);


    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVACK;
    /*length*/
    ToUINT24(result->start + 2,message->header.langtaglen + 16);
    /*flags*/
    ToUINT16(result->start + 5,0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);
    
    /*-------------------*/
    /* Add the errorcode */
    /*-------------------*/
    ToUINT16(result->start + 14 + message->header.langtaglen, errorcode);
}
Beispiel #6
0
/*-------------------------------------------------------------------------*/
int v1ProcessSrvTypeRqst(struct sockaddr_in* peeraddr,
                         SLPMessage message,
                         SLPBuffer* sendbuf,
                         int errorcode)
/*-------------------------------------------------------------------------*/
{
    char*                           type;
    char*                           end;
    char*                           slider;
    int                             i;
    int                             typelen;
    int                             numsrvtypes = 0;
    int                             size        = 0;
    SLPDDatabaseSrvTypeRqstResult*  db          = 0;
    SLPBuffer                       result      = *sendbuf;


    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if (SLPIntersectStringList(message->body.srvtyperqst.prlistlen,
                               message->body.srvtyperqst.prlist,
                               G_SlpdProperty.interfacesLen,
                               G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------------------------------------*/
    if (SLPIntersectStringList(message->body.srvtyperqst.scopelistlen,
                               message->body.srvtyperqst.scopelist,
                               G_SlpdProperty.useScopesLen,
                               G_SlpdProperty.useScopes) != 0)
    {
        /*------------------------------------*/
        /* Find service types in the database */
        /*------------------------------------*/
        errorcode = SLPDDatabaseSrvTypeRqstStart(message, &db);
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if (message->header.flags & SLP_FLAG_MCAST)
    {
        if (errorcode != 0 || db->srvtypelistlen == 0)
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }


    /*-----------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvtyperply */
    /*-----------------------------------------------------------------*/
    size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes
                  for num of service types */
    if (errorcode == 0)
    {
        if (db->srvtypelistlen)
        {
            /* there has to be at least one service type*/
            numsrvtypes = 1;

            /* count the rest of the service types */
            type = db->srvtypelist;
            for (i=0; i< db->srvtypelistlen; i++)
            {
                if (type[i] == ',')
                {
                    numsrvtypes += 1;
                }
            }

            /* figure out how much memory is required for srvtype strings */
            typelen = INT_MAX;
            errorcode = SLPv1ToEncoding(0,
                                        &typelen,
                                        message->header.encoding,  
                                        db->srvtypelist,
                                        db->srvtypelistlen);

            /* TRICKY: we add in the numofsrvtypes + 1 to make room for the */
            /* type length.  We can do this because the ',' of the comma    */
            /* delimited list is one byte.                                  */
            size = size + typelen + numsrvtypes + 1;
        }
        else
        {
            numsrvtypes = 0;
        }
    }

    /*-----------------*/
    /* Allocate memory */
    /*-----------------*/
    result = SLPBufferRealloc(result,size);
    if (result == 0)
    {
        errorcode = SLP_ERROR_INTERNAL_ERROR;
        goto FINISHED;
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVTYPERPLY;
    /*length*/
    ToUINT16(result->start + 2, size);
    /*flags - TODO set the flags correctly */
    *(result->start + 4) = message->header.flags |
                           (size > SLP_MAX_DATAGRAM_SIZE ? SLPv1_FLAG_OVERFLOW : 0);  
    /*dialect*/
    *(result->start + 5) = 0;
    /*language code*/
    memcpy(result->start + 6, message->header.langtag, 2);
    ToUINT16(result->start + 8, message->header.encoding);
    /*xid*/
    ToUINT16(result->start + 10, message->header.xid);

    /*-----------------------------*/
    /* Add rest of the SrvTypeRply */
    /*-----------------------------*/
    result->curpos = result->start + 12;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos += 2;
    if (errorcode == 0)
    {
        /* num of service types */
        ToUINT16(result->curpos, numsrvtypes);
        result->curpos += 2;

        /* service type strings */
        type = db->srvtypelist;
        slider = db->srvtypelist;
        end = &(type[db->srvtypelistlen]);
        for (i=0;i<numsrvtypes; i++)
        {
            while (slider < end && *slider != ',') slider++;

            typelen = size;
            /* put in the encoded service type */
            SLPv1ToEncoding(result->curpos + 2, 
                            &typelen,
                            message->header.encoding,
                            type,
                            slider - type);
            /* slip in the typelen */
            ToUINT16(result->curpos, typelen);
            result->curpos += 2;
            result->curpos += typelen;

            slider ++; /* skip comma */
            type = slider;
        }

        /* TODO - make sure we don't return generic types */
    }

    FINISHED:   
    if (db) SLPDDatabaseSrvTypeRqstEnd(db);

    *sendbuf = result;

    return errorcode;
}
Beispiel #7
0
/*-------------------------------------------------------------------------*/
int ProcessDASrvRqst(struct sockaddr_in* peeraddr,
                     SLPMessage message,
                     SLPBuffer* sendbuf,
                     int errorcode)
/*-------------------------------------------------------------------------*/
{
    SLPDAEntry      daentry;
    SLPBuffer       tmp     = 0;
    SLPDAEntry*     entry   = 0;
    void*           i       = 0;

    /* set up local data */
    memset(&daentry,0,sizeof(daentry));    

    /*---------------------------------------------------------------------*/
    /* Special case for when libslp asks slpd (through the loopback) about */
    /* a known DAs. Fill sendbuf with DAAdverts from all known DAs.        */
    /*---------------------------------------------------------------------*/
    if(ISLOCAL(peeraddr->sin_addr))
    {
        /* TODO: be smarter about how much memory is allocated here! */
        /* 4096 may not be big enough to handle all DAAdverts        */
        *sendbuf = SLPBufferRealloc(*sendbuf, 4096);
        if(*sendbuf == 0)
        {
            return SLP_ERROR_INTERNAL_ERROR;
        }

        if(errorcode == 0)
        {

            /* Note: The weird *sendbuf code is making a single SLPBuffer */
            /*       that contains multiple DAAdverts.  This is a special */
            /*       process that only happens for the DA SrvRqst through */
            /*       loopback to the SLPAPI                               */
            while(SLPDKnownDAEnum(&i,&entry) == 0)
            {
                if(SLPDKnownDAEntryToDAAdvert(errorcode,
                                              message->header.xid,
                                              entry,
                                              &tmp) == 0)
                {
                    if(((*sendbuf)->curpos) + (tmp->end - tmp->start) > (*sendbuf)->end)
                    {
                        break;
                    }

                    memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
                    (*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);
                }
            }

            /* Tack on a "terminator" DAAdvert */
            SLPDKnownDAEntryToDAAdvert(SLP_ERROR_INTERNAL_ERROR,
                                       message->header.xid,
                                       &daentry,
                                       &tmp);
            if(((*sendbuf)->curpos) + (tmp->end - tmp->start) <= (*sendbuf)->end)
            {
                memcpy((*sendbuf)->curpos, tmp->start, tmp->end - tmp->start);
                (*sendbuf)->curpos = ((*sendbuf)->curpos) + (tmp->end - tmp->start);
            }

            /* mark the end of the sendbuf */
            (*sendbuf)->end = (*sendbuf)->curpos;


            if(tmp)
            {
                SLPBufferFree(tmp);
            }
        }

        return errorcode;
    }


    /*---------------------------------------------------------------------*/
    /* Normal case where a remote Agent asks for a DA                      */
    /*---------------------------------------------------------------------*/
    if(G_SlpdProperty.isDA)
    {
        if(message->body.srvrqst.scopelistlen == 0 ||
           SLPIntersectStringList(message->body.srvrqst.scopelistlen, 
                                  message->body.srvrqst.scopelist,
                                  G_SlpdProperty.useScopesLen,
                                  G_SlpdProperty.useScopes))
        {
            /* fill out real structure */
            G_SlpdProperty.DATimestamp += 1;
            daentry.bootstamp = G_SlpdProperty.DATimestamp;
            daentry.langtaglen = G_SlpdProperty.localeLen;
            daentry.langtag = (char*)G_SlpdProperty.locale;
            daentry.urllen = G_SlpdProperty.myUrlLen;
            daentry.url = (char*)G_SlpdProperty.myUrl;
            daentry.scopelistlen = G_SlpdProperty.useScopesLen;
            daentry.scopelist = (char*)G_SlpdProperty.useScopes;
            daentry.attrlistlen = 0;
            daentry.attrlist = 0;
            daentry.spilistlen = 0;
            daentry.spilist = 0;
        }
        else
        {
            errorcode =  SLP_ERROR_SCOPE_NOT_SUPPORTED;
        }
    }
    else
    {
        errorcode = SLP_ERROR_MESSAGE_NOT_SUPPORTED;       
    }

    /* don't return errorcodes to multicast messages */
    if(errorcode != 0)
    {
        if(message->header.flags & SLP_FLAG_MCAST ||
           ISMCAST(peeraddr->sin_addr))
        {
            (*sendbuf)->end = (*sendbuf)->start;
            return errorcode;
        }
    }

    errorcode = SLPDKnownDAEntryToDAAdvert(errorcode,
                                           message->header.xid,
                                           &daentry,
                                           sendbuf);

    return errorcode;
}
Beispiel #8
0
/*-------------------------------------------------------------------------*/
void ProcessSASrvRqst(SLPDPeerInfo* peerinfo,
		      SLPMessage message,
		      SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int size = 0;
   
    if(message->body.srvrqst.scopelistlen == 0 ||
       SLPStringListIntersect(message->body.srvrqst.scopelistlen,
                              message->body.srvrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0 )
    {
        /*----------------------*/
        /* Send back a SAAdvert */
        /*----------------------*/
        
        /*-------------------------------------------------------------*/
        /* ensure the buffer is big enough to handle the whole srvrply */
        /*-------------------------------------------------------------*/
        size = message->header.langtaglen + 21; /* 14 bytes for header     */
                                                /*  2 bytes for url count  */
                                                /*  2 bytes for scope list len */
                                                /*  2 bytes for attr list len */
                                                /*  1 byte for authblock count */
        size += G_SlpdProperty.myUrlLen;
        size += G_SlpdProperty.useScopesLen;
        /* TODO: size += G_SlpdProperty.SAAttributes */
       
        result = SLPBufferRealloc(result,size);
        if(result == 0)
        {
	    /* TODO: out of memory, what should we do here! */
	    return;
        }

        /*----------------*/
        /* Add the header */
        /*----------------*/
        /*version*/
        *(result->start)       = 2;
        /*function id*/
        *(result->start + 1)   = SLP_FUNCT_SAADVERT;
        /*length*/
        ToUINT24(result->start + 2, size);
        /*flags*/
        ToUINT16(result->start + 5,
        size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
        /*ext offset*/
        ToUINT24(result->start + 7,0);
        /*xid*/
        ToUINT16(result->start + 10,message->header.xid);
        /*lang tag len*/
        ToUINT16(result->start + 12,message->header.langtaglen);
        /*lang tag*/
        memcpy(result->start + 14,
               message->header.langtag,
               message->header.langtaglen);
        
        /*--------------------------*/
        /* Add rest of the SAAdvert */
        /*--------------------------*/
        result->curpos = result->start + 14 + message->header.langtaglen;
        /* url len */
        ToUINT16(result->curpos, G_SlpdProperty.myUrlLen);
        result->curpos = result->curpos + 2;
        /* url */
        memcpy(result->start,G_SlpdProperty.myUrl,G_SlpdProperty.myUrlLen);
        result->curpos = result->curpos + G_SlpdProperty.myUrlLen;
        /* scope list len */
        ToUINT16(result->curpos, G_SlpdProperty.useScopesLen);
        result->curpos = result->curpos + 2;
        /* scope list */
        memcpy(result->start,G_SlpdProperty.useScopes,G_SlpdProperty.useScopesLen);
        result->curpos = result->curpos + G_SlpdProperty.useScopesLen;
        /* attr list len */
        /* ToUINT16(result->curpos,G_SlpdProperty.SAAttributesLen) */
        ToUINT16(result->curpos, 0);
        result->curpos = result->curpos + 2;
        /* attr list */
        /* memcpy(result->start,G_SlpdProperty.SAAttributes,G_SlpdProperty.SAAttributesLen) */
        /* authblock count */
        *(result->curpos) = 0;
    }
    else
    {
        /*--------------------------------*/
        /* Send back a SrvRply with error */
        /*--------------------------------*/
        if(message->header.flags & SLP_FLAG_MCAST)
	{
	    /* drop multicast SrvRqsts we can not answer */
	    result->end = result->start;   
	}
        else
	{
	    /*-------------------------------------------------------------*/
            /* ensure the buffer is big enough to handle the whole srvrply */
            /*-------------------------------------------------------------*/
            size = message->header.langtaglen + 18; /* 14 bytes for header     */
                                            /*  2 bytes for error code */
                                            /*  2 bytes for url count  */ 
   
            result = SLPBufferRealloc(result,size);
            if(result == 0)
            {
                /* TODO: out of memory, what should we do here! */
	        return;               
            }

            /*----------------*/
            /* Add the header */
            /*----------------*/
            /*version*/
            *(result->start)       = 2;
            /*function id*/
            *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
            /*length*/
            ToUINT24(result->start + 2, size);
            /*flags*/
            ToUINT16(result->start + 5,
            size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
            /*ext offset*/
            ToUINT24(result->start + 7,0);
            /*xid*/
            ToUINT16(result->start + 10,message->header.xid);
            /*lang tag len*/
            ToUINT16(result->start + 12,message->header.langtaglen);
            /*lang tag*/
            memcpy(result->start + 14,
            message->header.langtag,
            message->header.langtaglen);
    
            /*-------------------------*/
            /* Add rest of the SrvRply */
            /*-------------------------*/
            result->curpos = result->start + 14 + message->header.langtaglen;
            /* error code*/
            ToUINT16(result->curpos, SLP_ERROR_SCOPE_NOT_SUPPORTED);
            result->curpos = result->curpos + 2;
            /* urlentry count */
            ToUINT16(result->curpos, 0);
            result->curpos = result->curpos + 2;
        }
    }
}
Beispiel #9
0
/*-------------------------------------------------------------------------*/
void ProcessSrvDeReg(SLPDPeerInfo* peerinfo,
                     SLPMessage message,
                     SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int errorcode;

    if(message->header.flags & SLP_FLAG_MCAST)
    {
        /* don't do anything multicast SrvDeReg (set result empty) */
        result->end = result->start;
        return;
    }

    /*------------------------------------------*/
    /* TODO: make sure that we handle the scope */
    /*------------------------------------------*/
    if(SLPStringListIntersect(message->body.srvdereg.scopelistlen,
                              message->body.srvdereg.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes))
    {
        /*-------------------------------*/
        /* TODO: Validate the authblocks */
        /*-------------------------------*/
        
        /*--------------------------------------*/
        /* remove the service from the database */
        /*--------------------------------------*/
        if(SLPDDatabaseDeReg(&(message->body.srvdereg)) == 0)
        {
             errorcode = 0;
        }
        else
        {
            errorcode = SLP_ERROR_INTERNAL_ERROR;
        }
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    /*------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvack */
    /*------------------------------------------------------------*/
    result = SLPBufferRealloc(result,message->header.langtaglen + 16);
    
    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVACK;
    /*length*/
    ToUINT24(result->start + 2,message->header.langtaglen + 16);
    /*flags*/
    ToUINT16(result->start + 5,0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);
    
    /*-------------------*/
    /* Add the errorcode */
    /*-------------------*/
    ToUINT16(result->start + 14 + message->header.langtaglen, errorcode);
}
Beispiel #10
0
/*-------------------------------------------------------------------------*/
void IncomingStreamRead(SLPList* socklist, SLPDSocket* sock)
/*-------------------------------------------------------------------------*/
{
    int     bytesread;
    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)
        {

             /* allocate the recvbuf big enough for the whole message */
            sock->recvbuf = SLPBufferRealloc(sock->recvbuf,AsUINT24(peek+2));
            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:
                    sock->state = SOCKET_CLOSE;
                    break;                    
                default:
                    sock->state = STREAM_WRITE_FIRST;
                    IncomingStreamWrite(socklist, sock);
                }
            }
        }
        else
        {
            /* error in recv() */
            sock->state = SOCKET_CLOSE;
        }
    }
}
Beispiel #11
0
/*-------------------------------------------------------------------------*/
void ProcessSrvRqst(SLPDPeerInfo* peerinfo,
                    SLPMessage message,
                    SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int                     i;
    int                     size        = 0;
    int                     count       = 0;
    int                     found       = 0;
    SLPDDatabaseSrvUrl*     srvarray    = 0;
    int                     errorcode   = 0;
    

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if(SLPStringListIntersect(message->body.srvrqst.prlistlen,
                              message->body.srvrqst.prlist,
                              G_SlpdProperty.interfacesLen,
                              G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------------------*/
    /* Check to to see if a this is a special SrvRqst */
    /*------------------------------------------------*/
    if(SLPStringCompare(message->body.srvrqst.srvtypelen,
			message->body.srvrqst.srvtype,
			23,
			"service:directory-agent") == 0)
    {
        ProcessDASrvRqst(peerinfo,
			 message,
			 result);
        goto FINISHED;
    }
    if(SLPStringCompare(message->body.srvrqst.srvtypelen,
			message->body.srvrqst.srvtype,
			21,
			"service:service-agent") == 0)
    {
        ProcessSASrvRqst(peerinfo,
			 message,
			 result);
        goto FINISHED;
    }
   
    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if(SLPStringListIntersect(message->body.srvrqst.scopelistlen,
                              message->body.srvrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0)
    {
        /*-------------------------------*/
        /* Find services in the database */
        /*-------------------------------*/
        while(found == count)
        {
            count += SLPDPROCESS_RESULT_COUNT;
        
            if(srvarray) free(srvarray);
            srvarray = (SLPDDatabaseSrvUrl*)malloc(sizeof(SLPDDatabaseSrvUrl) * count);
            if(srvarray == 0)
            {
                found       = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        
            found = SLPDDatabaseFindSrv(&(message->body.srvrqst), srvarray, count);
            if(found < 0)
            {
                found = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        }
    }
    else
    { 
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }
   
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if(found <= 0 && (message->header.flags & SLP_FLAG_MCAST))
    {
        result->end = result->start;
        goto FINISHED;
    }   


    /*-------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvrply */
    /*-------------------------------------------------------------*/
    size = message->header.langtaglen + 18; /* 14 bytes for header     */
                                            /*  2 bytes for error code */
                                            /*  2 bytes for url count  */ 
    for(i=0;i<found;i++)
    {
        size += srvarray[i].urllen + 6; /*  1 byte for reserved  */
                                                /*  2 bytes for lifetime */
                                                /*  2 bytes for urllen   */
                                                /*  1 byte for authcount */
        
        /* TODO: Fix this for authentication */
    } 
    result = SLPBufferRealloc(result,size);
    if(result == 0)
    {
        found = 0;
        errorcode = SLP_ERROR_INTERNAL_ERROR;
    }

    
    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
    /*length*/
    ToUINT24(result->start + 2, size);
    /*flags*/
    ToUINT16(result->start + 5,
             size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);
    
    
    /*-------------------------*/
    /* Add rest of the SrvRply */
    /*-------------------------*/
    result->curpos = result->start + 14 + message->header.langtaglen;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    /* urlentry count */
    ToUINT16(result->curpos, found);
    result->curpos = result->curpos + 2;
    for(i=0;i<found;i++)
    {
        /* url-entry reserved */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;
        /* url-entry lifetime */
        ToUINT16(result->curpos,srvarray[i].lifetime);
        result->curpos = result->curpos + 2;
        /* url-entry urllen */
        ToUINT16(result->curpos,srvarray[i].urllen);
        result->curpos = result->curpos + 2;
        /* url-entry url */
        memcpy(result->curpos,srvarray[i].url,srvarray[i].urllen);
        result->curpos = result->curpos + srvarray[i].urllen;
        /* url-entry authcount */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;

        /* TODO: put in authentication stuff too */
    }
    
    FINISHED:   
    if(srvarray) free(srvarray);
}
Beispiel #12
0
/*-------------------------------------------------------------------------*/
void ProcessSrvRqstError(SLPMessage message, SLPBuffer result, int errorcode)
/*-------------------------------------------------------------------------*/
{
    int size;

    /*--------------------------------*/
    /* Send back a SrvRply with error */
    /*--------------------------------*/
    if(message->header.flags & SLP_FLAG_MCAST)
    {
        /* drop multicast SrvRqsts we can not answer */
        result->end = result->start;   
    }
    else
    {
        /*-------------------------------------------------------------*/
        /* ensure the buffer is big enough to handle the whole srvrply */
        /*-------------------------------------------------------------*/
        size = message->header.langtaglen + 18; /* 14 bytes for header     */
                                                /*  2 bytes for error code */
                                                /*  2 bytes for url count  */ 
    
        result = SLPBufferRealloc(result,size);
        if(result == 0)
        {
            /* TODO: out of memory, should we do anything else here! */
            result->end = result->start; 
            return;               
        }

        /*----------------*/
        /* Add the header */
        /*----------------*/
        /*version*/
        *(result->start)       = 2;
        /*function id*/
        *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
        /*length*/
        ToUINT24(result->start + 2, size);
        /*flags*/
        ToUINT16(result->start + 5,
        size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
        /*ext offset*/
        ToUINT24(result->start + 7,0);
        /*xid*/
        ToUINT16(result->start + 10,message->header.xid);
        /*lang tag len*/
        ToUINT16(result->start + 12,message->header.langtaglen);
        /*lang tag*/
        memcpy(result->start + 14,
        message->header.langtag,
        message->header.langtaglen);

        /*------------------------------------------*/
        /* Add rest of the SrvRply (with errorcode) */
        /*------------------------------------------*/
        result->curpos = result->start + 14 + message->header.langtaglen;
        /* error code*/
        ToUINT16(result->curpos, errorcode);
        result->curpos = result->curpos + 2;
        /* urlentry count */
        ToUINT16(result->curpos, 0);
        result->curpos = result->curpos + 2;
    }

}
Beispiel #13
0
/*-------------------------------------------------------------------------*/
void ProcessDASrvRqst(SLPDPeerInfo* peerinfo,
                      SLPMessage message,
                      SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int size = 0;
   
    if(G_SlpdProperty.isDA == 0)
    {
        /*----------------------------------------------------------------*/
        /* Do not send error codes or empty replies to multicast requests */
        /*----------------------------------------------------------------*/
        if(message->header.flags & SLP_FLAG_MCAST)
        {
            result->end = result->start;
            return;
        }   

	ProcessSrvRqstError(message, result, SLP_ERROR_MESSAGE_NOT_SUPPORTED);
	return;
    }

    if(message->body.srvrqst.scopelistlen == 0 ||
       SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                              message->body.srvrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0 )
    {
        /*----------------------*/
        /* Send back a DAAdvert */
        /*----------------------*/

        /* increment the value for DATimestamp */
        G_SlpdProperty.DATimestamp += 1;
        if(G_SlpdProperty.DATimestamp == 0) 
        {
           G_SlpdProperty.DATimestamp = 1;
        }  

        /*-------------------------------------------------------------*/
        /* ensure the buffer is big enough to handle the whole srvrply */
        /*-------------------------------------------------------------*/
        size = message->header.langtaglen + 29; /* 14 bytes for header     */
                                                /*  2 errorcode  */
                                                /*  4 bytes for timestamp */
                                                /*  2 bytes for url len */
                                                /*  2 bytes for scope list len */
                                                /*  2 bytes for attr list len */
                                                /*  2 bytes for spi str len */
                                                /*  1 byte for authblock count */

        size += G_SlpdProperty.myUrlLen;
        size += G_SlpdProperty.useScopesLen;
        /* TODO:  - we don't use attributes yet */
        /* size += G_SlpdProperty.SAAttributes; */
       
        result = SLPBufferRealloc(result,size);
        if(result == 0)
        {
	        /* TODO: out of memory, what should we do here! */
	        return;
        }

        /*----------------*/
        /* Add the header */
        /*----------------*/
        /*version*/
        *(result->start)       = 2;
        /*function id*/
        *(result->start + 1)   = SLP_FUNCT_DAADVERT;
        /*length*/
        ToUINT24(result->start + 2, size);
        /*flags*/
        ToUINT16(result->start + 5,
        size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
        /*ext offset*/
        ToUINT24(result->start + 7,0);
        /*xid*/
        ToUINT16(result->start + 10,message->header.xid);
        /*lang tag len*/
        ToUINT16(result->start + 12,message->header.langtaglen);
        /*lang tag*/
        memcpy(result->start + 14,
               message->header.langtag,
               message->header.langtaglen);
        
        /*--------------------------*/
        /* Add rest of the DAAdvert */
        /*--------------------------*/
        result->curpos = result->start + 14 + message->header.langtaglen;
        /* error code */
        ToUINT16(result->curpos,0);
        result->curpos = result->curpos + 2;
        /* timestamp */
        ToUINT32(result->curpos,G_SlpdProperty.DATimestamp);
        result->curpos = result->curpos + 4;
        /* url len */                       
        ToUINT16(result->curpos, G_SlpdProperty.myUrlLen);
        result->curpos = result->curpos + 2;
        /* url */
        memcpy(result->curpos,G_SlpdProperty.myUrl,G_SlpdProperty.myUrlLen);
        result->curpos = result->curpos + G_SlpdProperty.myUrlLen;
        /* scope list len */
        ToUINT16(result->curpos, G_SlpdProperty.useScopesLen);
        result->curpos = result->curpos + 2;
        /* scope list */
        memcpy(result->curpos,G_SlpdProperty.useScopes,G_SlpdProperty.useScopesLen);
        result->curpos = result->curpos + G_SlpdProperty.useScopesLen;
        /* attr list len */
        ToUINT16(result->curpos, 0);
        result->curpos = result->curpos + 2;
        /* attr list */
        /* memcpy(result->start,G_SlpdProperty.DAAttributes,G_SlpdProperty.DAAttributesLen) */
        /* result->curpos = result->curpos + G_SlpdProperty.DAAttributesLen */
        /* SPI List */
        ToUINT16(result->curpos,0);
        result->curpos = result->curpos + 2;
        /* authblock count */
        *(result->curpos) = 0;
        result->curpos = result->curpos + 1;
    }
    else
    {
        ProcessSrvRqstError(message, result, SLP_ERROR_SCOPE_NOT_SUPPORTED);
    }
}
Beispiel #14
0
/** Receives datagram messages.
 *
 * Receives messages from one of the sockets in the specified 
 * SLPXcastsSockets structure, @p sockets.
 * 
 * @param[in] sockets - A pointer to the SOPXcastSockets structure that 
 *    describes the sockets from which to read messages.
 * @param[out] buf - A pointer to an SLPBuffer that will contain the 
 *    received message upon successful return.
 * @param[out] peeraddr - A pointer to a sockaddr structure that will 
 *    contain the address of the peer from which the message was received.
 * @param[in,out] timeout - A pointer to the timeval structure that 
 *    indicates how much time to wait for a message to arrive.
 *
 * @return Zero on success, or a non-zero with errno set on failure.
 */
int SLPXcastRecvMessage(const SLPXcastSockets * sockets, SLPBuffer * buf,
      void * peeraddr, struct timeval * timeout)
{
   fd_set readfds;
   sockfd_t highfd;
   int i;
   int readable;
   int bytesread;
   int recvloop;
   char peek[16];
   int result = 0;

   /* recv loop */
   recvloop = 1;
   while (recvloop)
   {
      /* Set the readfds */
      FD_ZERO(&readfds);
      highfd = 0;
      for (i = 0; i < sockets->sock_count; i++)
      {
         FD_SET(sockets->sock[i],&readfds);
         if (sockets->sock[i] > highfd)
            highfd = sockets->sock[i];
      }

      /* Select */
      readable = select((int)(highfd + 1), &readfds, 0, 0, timeout);
      if (readable > 0)
      {
         /* Read the datagram */
         for (i = 0; i < sockets->sock_count; i++)
         {
            if (FD_ISSET(sockets->sock[i], &readfds))
            {
               /* Peek at the first 16 bytes of the header */
               socklen_t peeraddrlen = sizeof(struct sockaddr_storage);
               bytesread = recvfrom(sockets->sock[i], peek, 16, MSG_PEEK, 
                     peeraddr, &peeraddrlen);
               if (bytesread == 16
#ifdef _WIN32
                     /* Win32 returns WSAEMSGSIZE if the message is larger 
                      * than the requested size, even with MSG_PEEK. But if 
                      * this is the error code we can be sure that the 
                      * message is at least 16 bytes 
                      */
                     || (bytesread == -1 && WSAGetLastError() == WSAEMSGSIZE)
#endif
               )
               {
                  if (AS_UINT24(peek + 2) <=  SLP_MAX_DATAGRAM_SIZE)
                  {
                     *buf = SLPBufferRealloc(*buf, AS_UINT24(peek + 2));
                     bytesread = recv(sockets->sock[i], (char *)(*buf)->curpos,
                           (int)((*buf)->end - (*buf)->curpos), 0);

                     /* This should never happen but we'll be paranoid*/
                     if (bytesread != (int)AS_UINT24(peek + 2))
                        (*buf)->end = (*buf)->curpos + bytesread;

                     /* Message read. We're done! */
                     result = 0; 
                     recvloop = 0;
                     break;
                  }
                  else
                  {
                     /* we got a bad message, or one that is too big! */
#ifndef UNICAST_NOT_SUPPORTED
                     /* Reading SLP_MAX_DATAGRAM_SIZE bytes on the socket */
                     *buf = SLPBufferRealloc(*buf, SLP_MAX_DATAGRAM_SIZE);
                     bytesread = recv(sockets->sock[i], (char *)(*buf)->curpos,
                           (int)((*buf)->end - (*buf)->curpos), 0);
                     /* This should never happen but we'll be paranoid*/
                     if (bytesread != SLP_MAX_DATAGRAM_SIZE)
                        (*buf)->end = (*buf)->curpos + bytesread;

                     result = SLP_ERROR_RETRY_UNICAST;
                     recvloop = 0;
                     return result;
#endif
                  }
               }
               else
               {
                  /* Not even 16 bytes available */
               }
            }
         }   
      }
      else if (readable == 0)
      {
         result = -1;
         errno = ETIMEDOUT;
         recvloop = 0;
      }
      else
      {
         result = -1;
         recvloop = 0;
      }
   }
   return result;
}
Beispiel #15
0
/*-------------------------------------------------------------------------*/
int v1ProcessSrvDeReg(struct sockaddr_in* peeraddr,
                      SLPMessage message,
                      SLPBuffer* sendbuf,
                      int errorcode)
/*                                                                         */
/* Returns: non-zero if message should be silently dropped                 */
/*-------------------------------------------------------------------------*/
{
    SLPBuffer result = *sendbuf;

    /*--------------------------------------------------------------*/
    /* If errorcode is set, we can not be sure that message is good */
    /* Go directly to send response code  also do not process mcast */
    /* srvreg or srvdereg messages                                  */
    /*--------------------------------------------------------------*/
    if (errorcode || message->header.flags & SLP_FLAG_MCAST)
    {
        goto RESPOND;
    }


    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------------------------------------*/
    if (SLPIntersectStringList(message->body.srvdereg.scopelistlen,
                               message->body.srvdereg.scopelist,
                               G_SlpdProperty.useScopesLen,
                               G_SlpdProperty.useScopes))
    {
        /*--------------------------------------*/
        /* remove the service from the database */
        /*--------------------------------------*/
        errorcode = SLPDDatabaseDeReg(message);
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    RESPOND:
    /*---------------------------------------------------------*/
    /* don't do anything multicast SrvDeReg (set result empty) */
    /*---------------------------------------------------------*/
    if (message->header.flags & SLP_FLAG_MCAST)
    {

        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvack */
    /*------------------------------------------------------------*/
    result = SLPBufferRealloc(result, 14);
    if (result == 0)
    {
        errorcode = SLP_ERROR_INTERNAL_ERROR;
        goto FINISHED;
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVACK;
    /*length*/
    ToUINT16(result->start + 2, 14);
    /*flags - TODO set the flags correctly */
    *(result->start + 4) = 0;
    /*dialect*/
    *(result->start + 5) = 0;
    /*language code*/
    memcpy(result->start + 6, message->header.langtag, 2);
    ToUINT16(result->start + 8, message->header.encoding);
    /*xid*/
    ToUINT16(result->start + 10, message->header.xid);

    /*-------------------*/
    /* Add the errorcode */
    /*-------------------*/
    ToUINT16(result->start + 12, errorcode);

    FINISHED:
    *sendbuf = result;
    return errorcode;
}
Beispiel #16
0
/*-------------------------------------------------------------------------*/
void ProcessAttrRqst(SLPDPeerInfo* peerinfo,
                     SLPMessage message,
                     SLPBuffer result)
/*-------------------------------------------------------------------------*/
{
    int                     i;
    int                     attrlistlen = 0;
    int                     size        = 0;
    int                     count       = 0;
    int                     found       = 0;
    SLPDDatabaseAttr*       attrarray   = 0;
    int                     errorcode   = 0;
    

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if(SLPStringListIntersect(message->body.attrrqst.prlistlen,
                              message->body.attrrqst.prlist,
                              G_SlpdProperty.interfacesLen,
                              G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        return;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if(SLPStringListIntersect(message->body.attrrqst.scopelistlen,
                              message->body.attrrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) == 0)
    {
        result->end = result->start;
        return;
    }
    
    
    /*-------------------------------*/
    /* Find attributes in the database */
    /*-------------------------------*/
    while(found == count)
    {
        count += SLPDPROCESS_RESULT_COUNT;
        
        if(attrarray) free(attrarray);
        attrarray = (SLPDDatabaseAttr*)malloc(sizeof(SLPDDatabaseAttr) * count);
        if(attrarray == 0)
        {
            found       = 0;
            errorcode   = SLP_ERROR_INTERNAL_ERROR;
            break;
        }
        
        found = SLPDDatabaseFindAttr(&(message->body.attrrqst), attrarray, count);
        if(found < 0)
        {
            found = 0;
            errorcode   = SLP_ERROR_INTERNAL_ERROR;
            break;
        }
    }

    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if(found <= 0 && (message->header.flags & SLP_FLAG_MCAST))
    {
        if(attrarray) free(attrarray);
        result->end = result->start;
        return;
    }

    /*--------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole attrrply */
    /*--------------------------------------------------------------*/
    size = message->header.langtaglen + 20; /* 14 bytes for header     */
                                            /*  2 bytes for error code */
                                            /*  2 bytes for attr-list len */
                                            /*  2 bytes for the authblockcount */
    for (i=0;i<found;i++)
    {
        attrlistlen += attrarray[i].attrlen;
    }
    size += attrlistlen;
    

    /*-------------------*/
    /* Alloc the  buffer */
    /*-------------------*/
    result = SLPBufferRealloc(result,size);
    if(result == 0)
    {
        found = 0;
        errorcode = SLP_ERROR_INTERNAL_ERROR;
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_ATTRRPLY;
    /*length*/
    ToUINT24(result->start + 2,size);
    /*flags*/
    ToUINT16(result->start + 5,
             size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);
    
    /*--------------------------*/
    /* Add rest of the AttrRqst */
    /*--------------------------*/
    result->curpos = result->start + 14 + message->header.langtaglen;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    /* attr-list len */
    ToUINT16(result->curpos, attrlistlen);
    result->curpos = result->curpos + 2;
    for(i=0;i<found;i++)
    {
        memcpy(result->curpos,attrarray[i].attr,attrarray[i].attrlen);
        result->curpos = result->curpos + attrarray[i].attrlen;
    }
    
    /* TODO: no auth block */
    ToUINT16(result->curpos, 0);

    if(attrarray) free(attrarray);
}        
Beispiel #17
0
/*-------------------------------------------------------------------------*/
int v1ProcessAttrRqst(struct sockaddr_in* peeraddr,
                      SLPMessage message,
                      SLPBuffer* sendbuf,
                      int errorcode)
/*-------------------------------------------------------------------------*/
{
    SLPDDatabaseAttrRqstResult* db              = 0;
    int                         attrlen     = 0;
    int                         size        = 0;
    SLPBuffer                   result      = *sendbuf;

    /*--------------------------------------------------------------*/
    /* If errorcode is set, we can not be sure that message is good */
    /* Go directly to send response code                            */
    /*--------------------------------------------------------------*/
    if (errorcode)
    {
        goto RESPOND;
    }

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if (SLPIntersectStringList(message->body.attrrqst.prlistlen,
                               message->body.attrrqst.prlist,
                               G_SlpdProperty.interfacesLen,
                               G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if (SLPIntersectStringList(message->body.attrrqst.scopelistlen,
                               message->body.attrrqst.scopelist,
                               G_SlpdProperty.useScopesLen,
                               G_SlpdProperty.useScopes))
    {
        /*---------------------------------*/
        /* Find attributes in the database */
        /*---------------------------------*/
        errorcode = SLPDDatabaseAttrRqstStart(message,&db);
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    RESPOND:
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if (message->header.flags & SLP_FLAG_MCAST)
    {
        if (errorcode != 0 || db->attrlistlen == 0)
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }

    /*--------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole attrrply */
    /*--------------------------------------------------------------*/
    size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes
                for attr-list len */
    if (errorcode == 0)
    {

        attrlen = INT_MAX;
        errorcode = SLPv1ToEncoding(0, &attrlen,
                                    message->header.encoding,  
                                    db->attrlist,
                                    db->attrlistlen);
        size += attrlen;
    }

    /*-------------------*/
    /* Alloc the  buffer */
    /*-------------------*/
    result = SLPBufferRealloc(result,size);
    if (result == 0)
    {
        errorcode = SLP_ERROR_INTERNAL_ERROR;
        goto FINISHED;
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_ATTRRPLY;
    /*length*/
    ToUINT16(result->start + 2, size);
    /*flags - TODO set the flags correctly */
    *(result->start + 4) = message->header.flags |
                           (size > SLP_MAX_DATAGRAM_SIZE ? SLPv1_FLAG_OVERFLOW : 0);  
    /*dialect*/
    *(result->start + 5) = 0;
    /*language code*/
    memcpy(result->start + 6, message->header.langtag, 2);
    ToUINT16(result->start + 8, message->header.encoding);
    /*xid*/
    ToUINT16(result->start + 10, message->header.xid);

    /*--------------------------*/
    /* Add rest of the AttrRply */
    /*--------------------------*/
    result->curpos = result->start + 12;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2; 
    if (errorcode == 0)
    {
        /* attr-list len */
        ToUINT16(result->curpos, attrlen);
        result->curpos = result->curpos + 2;
        attrlen = size;
        SLPv1ToEncoding(result->curpos, &attrlen,
                        message->header.encoding,
                        db->attrlist,
                        db->attrlistlen);
        result->curpos = result->curpos + attrlen; 
    }

    FINISHED:
    *sendbuf = result;
    if (db) SLPDDatabaseAttrRqstEnd(db);

    return errorcode;
}        
Beispiel #18
0
/*=========================================================================*/ 
SLPError NetworkRqstRply(int sock,
                         struct sockaddr_in* destaddr,
                         const char* langtag,
                         char* buf,
                         char buftype,
                         int bufsize,
                         NetworkRqstRplyCallback callback,
                         void * cookie)
/* Transmits and receives SLP messages via multicast convergence algorithm */
/*                                                                         */
/* Returns  -    SLP_OK on success                                         */
/*=========================================================================*/ 
{
    struct timeval      timeout;
    struct sockaddr_in  peeraddr;
    SLPBuffer           sendbuf         = 0;
    SLPBuffer           recvbuf         = 0;
    SLPMessage          msg             = 0;
    SLPError            result          = 0;
#ifdef WIN32 /* on WIN32 setsockopt takes a const char * argument */
    char                socktype        = 0;
#else
    int                 socktype        = 0;
#endif
    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                 timeouts[MAX_RETRANSMITS];

    /*----------------------------------------------------*/
    /* Save off a few things we don't want to recalculate */
    /*----------------------------------------------------*/
    langtaglen = strlen(langtag);
    xid = SLPXidGenerate();
    mtu = SLPPropertyAsInteger(SLPGetProperty("net.slp.MTU"));
    sendbuf = SLPBufferAlloc(mtu);
    if(sendbuf == 0)
    {                 
        result = SLP_MEMORY_ALLOC_FAILED;
        goto CLEANUP;
    }

    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.DADiscovertTimeouts"),
                                   timeouts,
                                   MAX_RETRANSMITS );
        /* SLP_FUNCT_DASRVRQST is a fake function.  We really want to */
        /* send a SRVRQST                                             */
        buftype = SLP_FUNCT_SRVRQST;
    }
     
    /* Figure unicast/multicast,TCP/UDP, wait and time out stuff */
    if(ntohl(destaddr->sin_addr.s_addr) > 0xe0000000)
    {
        /* Multicast or broadcast */
        maxwait = SLPPropertyAsInteger(SLPGetProperty("net.slp.multicastMaximumWait"));
        SLPPropertyAsIntegerVector(SLPGetProperty("net.slp.multicastTimeouts"), 
                                   timeouts, 
                                   MAX_RETRANSMITS );
        socktype = SOCK_DGRAM;
        xmitcount = 0;
    }
    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);
        socktype = SOCK_STREAM;
        xmitcount = MAX_RETRANSMITS;
    }
    
    
    
    /*--------------------------------*/
    /* Allocate memory for the prlist */
    /*--------------------------------*/
    prlist = (char*)malloc(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;
        }
        
        size = 14 + langtaglen + 2 + prlistlen + bufsize;
        if(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*/
        ToUINT16(sendbuf->start + 5, socktype == SOCK_STREAM ? 0 : 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*/
        memcpy(sendbuf->start + 14, langtag, langtaglen);
        sendbuf->curpos = sendbuf->start + langtaglen + 14 ;

        /*-----------------------------------*/
        /* Add the prlist to the send buffer */
        /*-----------------------------------*/
        if( buftype == SLP_FUNCT_SRVRQST ||
            buftype == SLP_FUNCT_ATTRRQST ||
            buftype == SLP_FUNCT_SRVTYPERQST)
        {
            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,
                                       sendbuf,
                                       destaddr,
                                       &timeout);
        if(result != 0)
        {
            /* we could not send the message for some reason */
            /* we're done */
            result = SLP_NETWORK_ERROR;
            goto FINISHED;
        }
            
 
        /*----------------*/
        /* Main recv loop */
        /*----------------*/
        while(1)
        {
            
            if(SLPNetworkRecvMessage(sock,
                                     &recvbuf,
                                     &peeraddr,
                                     &timeout) != 0)
            {
                /* An error occured while receiving the message */
                /* probably a just time out error. Retry send.  */
                break;
            }
             
            /* Parse the message and call callback */
            msg = SLPMessageRealloc(msg);
            if(msg == 0)
            {
                result = SLP_MEMORY_ALLOC_FAILED;
                goto FINISHED;
            }

            if(SLPMessageParseBuffer(recvbuf, msg) == 0)
            {
                if (msg->header.xid == xid)
                {
                    rplycount = rplycount + 1;
                    if(callback(result, msg, cookie) == 0)
                    {
                        goto CLEANUP;
                    }
                }
            }
            
            if(socktype == SOCK_STREAM)
            {
                goto FINISHED;
            }

            /* add the peer to the previous responder list */
            if(prlistlen != 0)
            {
                strcat(prlist,",");
            }
            strcat(prlist,inet_ntoa(peeraddr.sin_addr));
            prlistlen =  strlen(prlist); 
        }
    }

    FINISHED:
    /*----------------*/
    /* We're all done */
    /*----------------*/
    if(rplycount == 0)
    {
        result = SLP_NETWORK_TIMED_OUT;
    }

    /*-------------------------------------*/
    /* Notify the callback that we're done */
    /*-------------------------------------*/
    callback(SLP_LAST_CALL,msg,cookie);
    
    /*----------------*/
    /* Free resources */
    /*----------------*/
    CLEANUP:
    if(prlist) free(prlist);
    SLPBufferFree(sendbuf);
    SLPBufferFree(recvbuf);
    SLPMessageFree(msg);
    close(sock);

    return result;
}
Beispiel #19
0
/*=========================================================================*/ 
int SLPNetworkRecvMessage(int sockfd,
                          int socktype,
                          SLPBuffer* buf,
                          struct sockaddr_in* peeraddr,
                          struct timeval* timeout)
/* Receives a message                                                      */
/*                                                                         */
/* Returns  -    zero on success, non-zero on failure                      */
/*                                                                         */
/* errno         ENOTCONN error during read                                */
/*               ETIME read timed out                                      */
/*               ENOMEM out of memory                                      */
/*               EINVAL parse error                                        */
/*=========================================================================*/ 
{
    int         xferbytes;
    fd_set      readfds;
    char        peek[16];
    int         peeraddrlen = sizeof(struct sockaddr_in);

    /*---------------------------------------------------------------*/
    /* take a peek at the packet to get version and size information */
    /*---------------------------------------------------------------*/
    FD_ZERO(&readfds);
    FD_SET(sockfd, &readfds);
    xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout);
    if(xferbytes > 0)
    {
        if(socktype == SOCK_DGRAM)
        {
            xferbytes = recvfrom(sockfd,
                                 peek,
                                 16,
                                 MSG_PEEK,
                                 (struct sockaddr *)peeraddr,
                                 &peeraddrlen);
        }
        else
        {
            xferbytes = recv(sockfd,
                             peek,
                             16,
                             MSG_PEEK);
        }

        if(xferbytes <= 0)
        {
#ifdef WIN32
            if(WSAGetLastError() != WSAEMSGSIZE)
            {
                errno = ENOTCONN;
                return -1;
            }
#else
            errno = ENOTCONN;
            return -1;
#endif
        }
    }
    else if(xferbytes == 0)
    {
        errno = ETIMEDOUT;
        return -1;
    }
    else
    {
        errno = ENOTCONN;
        return -1;
    }

    /*------------------------------*/
    /* Read the rest of the message */
    /*------------------------------*/
    /* check the version */
    if(*peek == 2)
    {
        /* allocate the recvmsg big enough for the whole message */
        *buf = SLPBufferRealloc(*buf, AsUINT24(peek + 2));
        if(*buf)
        {
            while((*buf)->curpos < (*buf)->end)
            {
                FD_ZERO(&readfds);
                FD_SET(sockfd, &readfds);
                xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout);
                if(xferbytes > 0)
                {
                    xferbytes = recv(sockfd,
                                     (*buf)->curpos, 
                                     (*buf)->end - (*buf)->curpos, 
                                     0);
                    if(xferbytes > 0)
                    {
                        (*buf)->curpos = (*buf)->curpos + xferbytes;
                    }
                    else
                    {
                        errno = ENOTCONN;
                        return -1;
                    }
                }
                else if(xferbytes == 0)
                {
                    errno = ETIMEDOUT;
                    return -1;
                }
                else
                {
                    errno =  ENOTCONN;
                    return -1;
                }
            } /* end of main read while. */  
        }
        else
        {
            errno = ENOMEM;
            return -1;
        }
    }
    else
    {
        errno = EINVAL;
        return -1;
    }

    return 0;
}
Beispiel #20
0
/** Read inbound stream data.
 *
 * @param[in] socklist - The list of monitored sockets.
 * @param[in] sock - The socket to be read.
 *
 * @internal
 */
static void IncomingStreamRead(SLPList * socklist, SLPDSocket * sock)
{
   int bytesread;
   size_t recvlen = 0;
   char peek[16];
   socklen_t peeraddrlen = sizeof(struct sockaddr_storage);

   if (sock->state == STREAM_READ_FIRST)
   {
      /*---------------------------------------------------*/
      /* take a peek at the packet to get size information */
      /*---------------------------------------------------*/
      bytesread = recvfrom(sock->fd, (char *)peek, 16, MSG_PEEK,
            (struct sockaddr *)&sock->peeraddr, &peeraddrlen);
      if (bytesread > 0 && bytesread >= (*peek == 2? 5: 4))
      {
         recvlen = PEEK_LENGTH(peek);

         /* 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, (char *)sock->recvbuf->curpos,
            (int)(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) {
            if (!sock->sendbuf)
               /* Some of the error handling code expects a sendbuf to be available
                * to be emptied, so make sure there is at least a minimal buffer
                */
               sock->sendbuf = SLPBufferAlloc(1);
            switch (SLPDProcessMessage(&sock->peeraddr,
                  &sock->localaddr, sock->recvbuf, &sock->sendbuf, 0))
            {
               case SLP_ERROR_PARSE_ERROR:
               case SLP_ERROR_VER_NOT_SUPPORTED:
               case SLP_ERROR_MESSAGE_NOT_SUPPORTED:
                  sock->state = SOCKET_CLOSE;
                  break;

               default:
                  if (!sock->sendbuf || sock->sendbuf->end == sock->sendbuf->start)
                  {
                     /* no answer available, just close socket */
                     sock->state = SOCKET_CLOSE;
                     break;
                  }

                  /* some clients cannot cope with the OVERFLOW
                   * bit set on a TCP stream, so always clear it
                   */
                  if (sock->sendbuf->end - sock->sendbuf->start > 5)
                  {
                     if (sock->sendbuf->start[0] == 1)
                        sock->sendbuf->start[4] &= ~SLPv1_FLAG_OVERFLOW;
                     else
                        sock->sendbuf->start[5] &= ~(SLP_FLAG_OVERFLOW >> 8);
                  }
                  sock->state = STREAM_WRITE_FIRST;
                  IncomingStreamWrite(socklist, sock);
            }
         }
      }
Beispiel #21
0
/*-------------------------------------------------------------------------*/
int ProcessSrvRqst(struct sockaddr_in* peeraddr,
                   SLPMessage message,
                   SLPBuffer* sendbuf,
                   int errorcode)
/*-------------------------------------------------------------------------*/
{
    int                     i;
    int                     size        = 0;
    int                     count       = 0;
    int                     found       = 0;
    SLPDDatabaseSrvUrl*     srvarray    = 0;
    SLPBuffer               result      = *sendbuf;

    /*--------------------------------------------------------------*/
    /* If errorcode is set, we can not be sure that message is good */
    /* Go directly to send response code                            */
    /*--------------------------------------------------------------*/
    if(errorcode)
    {
        goto RESPOND;
    }

    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if(SLPIntersectStringList(message->body.srvrqst.prlistlen,
                              message->body.srvrqst.prlist,
                              G_SlpdProperty.interfacesLen,
                              G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------------------*/
    /* Check to to see if a this is a special SrvRqst */
    /*------------------------------------------------*/
    if(SLPCompareString(message->body.srvrqst.srvtypelen,
                        message->body.srvrqst.srvtype,
                        23,
                        "service:directory-agent") == 0)
    {
        errorcode = ProcessDASrvRqst(peeraddr, message, sendbuf, errorcode);
        return errorcode;
    }
    if(SLPCompareString(message->body.srvrqst.srvtypelen,
                        message->body.srvrqst.srvtype,
                        21,
                        "service:service-agent") == 0)
    {
        errorcode = ProcessSASrvRqst(peeraddr, message, sendbuf, errorcode);
        return errorcode;
    }

    /* TODO: check the spi list of the message and return                  */
    /*       AUTHENTICATION_UNKNOWN since we do not do authentication yet  */

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------ -----------------------------*/
    if(SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                              message->body.srvrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0)
    {
        /*-------------------------------*/
        /* Find services in the database */
        /*-------------------------------*/
        while(found == count)
        {
            count += G_SlpdProperty.maxResults;

            if(srvarray) free(srvarray);
            srvarray = (SLPDDatabaseSrvUrl*)malloc(sizeof(SLPDDatabaseSrvUrl) * count);
            if(srvarray == 0)
            {
                found       = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }

            found = SLPDDatabaseFindSrv(&(message->body.srvrqst), srvarray, count);
            if(found < 0)
            {
                found = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        }

        /* remember the amount found if is really big for next time */
        if(found > G_SlpdProperty.maxResults)
        {
            G_SlpdProperty.maxResults = found;
        }
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }


    RESPOND:
    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if(found == 0 ||
       errorcode != 0)
    {
        if(message->header.flags & SLP_FLAG_MCAST ||
           ISMCAST(peeraddr->sin_addr))
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }

    /*-------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvrply */
    /*-------------------------------------------------------------*/
    size = message->header.langtaglen + 18; /* 14 bytes for header     */
                                            /*  2 bytes for error code */
                                            /*  2 bytes for url count  */
    if(errorcode == 0)
    {
        for(i=0;i<found;i++)
        {
            size += srvarray[i].urllen + 6; /*  1 byte for reserved  */
            /*  2 bytes for lifetime */
            /*  2 bytes for urllen   */
            /*  1 byte for authcount */

            /* TODO: Fix this for authentication */
        } 
        result = SLPBufferRealloc(result,size);
        if(result == 0)
        {
            found = 0;
            errorcode = SLP_ERROR_INTERNAL_ERROR;
            goto FINISHED;
        }
    }

    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 2;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVRPLY;
    /*length*/
    ToUINT24(result->start + 2, size);
    /*flags*/
    ToUINT16(result->start + 5,
             size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
    /*ext offset*/
    ToUINT24(result->start + 7,0);
    /*xid*/
    ToUINT16(result->start + 10,message->header.xid);
    /*lang tag len*/
    ToUINT16(result->start + 12,message->header.langtaglen);
    /*lang tag*/
    memcpy(result->start + 14,
           message->header.langtag,
           message->header.langtaglen);


    /*-------------------------*/
    /* Add rest of the SrvRply */
    /*-------------------------*/
    result->curpos = result->start + 14 + message->header.langtaglen;
    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos = result->curpos + 2;
    /* urlentry count */
    ToUINT16(result->curpos, found);
    result->curpos = result->curpos + 2;
    for(i=0;i<found;i++)
    {
        /* url-entry reserved */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;
        /* url-entry lifetime */
        ToUINT16(result->curpos,srvarray[i].lifetime);
        result->curpos = result->curpos + 2;
        /* url-entry urllen */
        ToUINT16(result->curpos,srvarray[i].urllen);
        result->curpos = result->curpos + 2;
        /* url-entry url */
        memcpy(result->curpos,srvarray[i].url,srvarray[i].urllen);
        result->curpos = result->curpos + srvarray[i].urllen;
        /* url-entry authcount */
        *result->curpos = 0;        
        result->curpos = result->curpos + 1;

        /* TODO: put in authentication stuff too */
    }

    FINISHED:   
    if(srvarray) free(srvarray);

    *sendbuf = result;
    return errorcode;
}
Beispiel #22
0
/*-------------------------------------------------------------------------*/
int v1ProcessSrvTypeRqst(struct sockaddr_in* peeraddr,
                         SLPMessage message,
                         SLPBuffer* sendbuf,
                         int errorcode)
/*-------------------------------------------------------------------------*/
{
    int                     i, typelen;
    int                     size         = 0;
    int                     count        = 0;
    int                     found        = 0;
    SLPDDatabaseSrvType*    srvtypearray = 0;
    SLPBuffer               result       = *sendbuf;


    /*-------------------------------------------------*/
    /* Check for one of our IP addresses in the prlist */
    /*-------------------------------------------------*/
    if(SLPIntersectStringList(message->body.srvtyperqst.prlistlen,
                              message->body.srvtyperqst.prlist,
                              G_SlpdProperty.interfacesLen,
                              G_SlpdProperty.interfaces))
    {
        result->end = result->start;
        goto FINISHED;
    }

    /*------------------------------------*/
    /* Make sure that we handle the scope */
    /*------------------------------------*/
    if(SLPIntersectStringList(message->body.srvtyperqst.scopelistlen,
                              message->body.srvtyperqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0)
    {
        /*------------------------------------*/
        /* Find service types in the database */
        /*------------------------------------*/
        while(found == count)
        {
            count += G_SlpdProperty.maxResults;

            if(srvtypearray) free(srvtypearray);
            srvtypearray = (SLPDDatabaseSrvType*)malloc(sizeof(SLPDDatabaseSrvType) * count);
            if(srvtypearray == 0)
            {
                found       = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }

            found = SLPDDatabaseFindType(&(message->body.srvtyperqst), srvtypearray, count);
            if(found < 0)
            {
                found = 0;
                errorcode   = SLP_ERROR_INTERNAL_ERROR;
                break;
            }
        }

        /* remember the amount found if is really big for next time */
        if(found > G_SlpdProperty.maxResults)
        {
            G_SlpdProperty.maxResults = found;
        }
    }
    else
    {
        errorcode = SLP_ERROR_SCOPE_NOT_SUPPORTED;
    }

    /*----------------------------------------------------------------*/
    /* Do not send error codes or empty replies to multicast requests */
    /*----------------------------------------------------------------*/
    if(message->header.flags & SLP_FLAG_MCAST)
    {
        if(found == 0 || errorcode != 0)
        {
            result->end = result->start;
            goto FINISHED;  
        }
    }


    /*-----------------------------------------------------------------*/
    /* ensure the buffer is big enough to handle the whole srvtyperply */
    /*-----------------------------------------------------------------*/
    size = 16; /* 12 bytes for header, 2 bytes for error code, 2 bytes
          for srvtype count  */
    if(errorcode == 0)
    {
        for(i=0;i<found;i++)
        {
            typelen = INT_MAX;
            errorcode = SLPv1ToEncoding(0, &typelen,
                                        message->header.encoding,  
                                        srvtypearray[i].type,
                                        srvtypearray[i].typelen);
            if(errorcode)
                break;
            size += typelen + 2;  /*  2 byte for length */
        }
    }
    result = SLPBufferRealloc(result,size);
    if(result == 0)
    {
        found = 0;
        errorcode = SLP_ERROR_INTERNAL_ERROR;
    }


    /*----------------*/
    /* Add the header */
    /*----------------*/
    /*version*/
    *(result->start)       = 1;
    /*function id*/
    *(result->start + 1)   = SLP_FUNCT_SRVTYPERPLY;
    /*length*/
    ToUINT16(result->start + 2, size);
    /*flags - TODO set the flags correctly */
    *(result->start + 4) = message->header.flags |
                           (size > SLP_MAX_DATAGRAM_SIZE ? SLPv1_FLAG_OVERFLOW : 0);  
    /*dialect*/
    *(result->start + 5) = 0;
    /*language code*/
    memcpy(result->start + 6, message->header.langtag, 2);
    ToUINT16(result->start + 8, message->header.encoding);
    /*xid*/
    ToUINT16(result->start + 10, message->header.xid);

    /*-----------------------------*/
    /* Add rest of the SrvTypeRply */
    /*-----------------------------*/
    result->curpos = result->start + 12;

    /* error code*/
    ToUINT16(result->curpos, errorcode);
    result->curpos += 2;

    /* service type count */
    ToUINT16(result->curpos, found);
    result->curpos += 2;

    /* TODO - make sure we don't return generic types */
    for(i=0;i<found;i++)
    {
        typelen = size;
        SLPv1ToEncoding(result->curpos + 2, &typelen,
                        message->header.encoding,  
                        srvtypearray[i].type,
                        srvtypearray[i].typelen);
        ToUINT16(result->curpos, srvtypearray[i].typelen);
        result->curpos += 2 + typelen;
    }

    FINISHED:   
    if(srvtypearray) free(srvtypearray);
    *sendbuf = result;
    return errorcode;
}
Beispiel #23
0
/*-------------------------------------------------------------------------*/
int ProcessSASrvRqst(struct sockaddr_in* peeraddr,
                     SLPMessage message,
                     SLPBuffer* sendbuf,
                     int errorcode)
/*-------------------------------------------------------------------------*/
{
    int size = 0;
    SLPBuffer result = *sendbuf;

    if(message->body.srvrqst.scopelistlen == 0 ||
       SLPIntersectStringList(message->body.srvrqst.scopelistlen,
                              message->body.srvrqst.scopelist,
                              G_SlpdProperty.useScopesLen,
                              G_SlpdProperty.useScopes) != 0)
    {
        /*----------------------*/
        /* Send back a SAAdvert */
        /*----------------------*/

        /*--------------------------------------------------------------*/
        /* ensure the buffer is big enough to handle the whole SAAdvert */
        /*--------------------------------------------------------------*/
        size = message->header.langtaglen + 21; /* 14 bytes for header     */
                                                /*  2 bytes for url count  */
                                                /*  2 bytes for scope list len */
                                                /*  2 bytes for attr list len */
                                                /*  1 byte for authblock count */
        size += G_SlpdProperty.myUrlLen;
        size += G_SlpdProperty.useScopesLen;
        /* TODO: size += G_SlpdProperty.SAAttributes */

        result = SLPBufferRealloc(result,size);
        if(result == 0)
        {
            /* TODO: out of memory, what should we do here! */
            errorcode = SLP_ERROR_INTERNAL_ERROR;
            goto FINISHED;
        }

        /*----------------*/
        /* Add the header */
        /*----------------*/
        /*version*/
        *(result->start)       = 2;
        /*function id*/
        *(result->start + 1)   = SLP_FUNCT_SAADVERT;
        /*length*/
        ToUINT24(result->start + 2, size);
        /*flags*/
        ToUINT16(result->start + 5,
                 size > SLP_MAX_DATAGRAM_SIZE ? SLP_FLAG_OVERFLOW : 0);
        /*ext offset*/
        ToUINT24(result->start + 7,0);
        /*xid*/
        ToUINT16(result->start + 10,message->header.xid);
        /*lang tag len*/
        ToUINT16(result->start + 12,message->header.langtaglen);
        /*lang tag*/
        memcpy(result->start + 14,
               message->header.langtag,
               message->header.langtaglen);

        /*--------------------------*/
        /* Add rest of the SAAdvert */
        /*--------------------------*/
        result->curpos = result->start + 14 + message->header.langtaglen;
        /* url len */
        ToUINT16(result->curpos, G_SlpdProperty.myUrlLen);
        result->curpos = result->curpos + 2;
        /* url */
        memcpy(result->curpos,G_SlpdProperty.myUrl,G_SlpdProperty.myUrlLen);
        result->curpos = result->curpos + G_SlpdProperty.myUrlLen;
        /* scope list len */
        ToUINT16(result->curpos, G_SlpdProperty.useScopesLen);
        result->curpos = result->curpos + 2;
        /* scope list */
        memcpy(result->curpos,G_SlpdProperty.useScopes,G_SlpdProperty.useScopesLen);
        result->curpos = result->curpos + G_SlpdProperty.useScopesLen;
        /* attr list len */
        /* ToUINT16(result->curpos,G_SlpdProperty.SAAttributesLen) */
        ToUINT16(result->curpos, 0);
        result->curpos = result->curpos + 2;
        /* attr list */
        /* memcpy(result->start,G_SlpdProperty.SAAttributes,G_SlpdProperty.SAAttributesLen) */
        /* authblock count */
        *(result->curpos) = 0;
    }

    FINISHED:

    *sendbuf = result;

    return errorcode;
}
Beispiel #24
0
/*=========================================================================*/ 
SLPError NetworkRecvMessage(int sockfd,
                           SLPBuffer buf,
                           struct timeval* timeout,
                           struct sockaddr* peeraddr,
                           int* peeraddrlen)
/* Receives a message                                                      */
/*                                                                         */
/* Returns  -    SLP_OK, SLP_NETWORK_TIMEOUT, SLP_NETWORK_ERROR, or        */
/*               SLP_PARSE_ERROR.                                          */
/*=========================================================================*/ 
{
    SLPError    result      = SLP_OK;
    int         xferbytes;
    fd_set      readfds;
    char        peek[16];
    
    /*---------------------------------------------------------------*/
    /* take a peek at the packet to get version and size information */
    /*---------------------------------------------------------------*/
    FD_ZERO(&readfds);
    FD_SET(sockfd, &readfds);
    xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout);
    if(xferbytes > 0)
    {
        xferbytes = recvfrom(sockfd,
                             peek,
                             16,
                             MSG_PEEK,
                             peeraddr,
                             peeraddrlen);
        if(xferbytes <= 0)
        {
            result = SLP_NETWORK_ERROR;
        } 
    }
    else if(xferbytes == 0)
    {
        result = SLP_NETWORK_TIMED_OUT;
    }
    else
    {
        result = SLP_NETWORK_ERROR;
    }

    /*---------------------------------------*/
    /* return now if peek was not successful */
    /*---------------------------------------*/
    if(result) return result;

    
    /*------------------------------*/
    /* Read the rest of the message */
    /*------------------------------*/
    /* check the version */
    if(*peek == 2)
    {
        /* allocate the recvmsg big enough for the whole message */
        if(SLPBufferRealloc(buf, AsUINT24(peek + 2)))
        {
            while(buf->curpos < buf->end)
            {
                FD_ZERO(&readfds);
                FD_SET(sockfd, &readfds);
                xferbytes = select(sockfd + 1, &readfds, 0 , 0, timeout);
                if(xferbytes > 0)
                {
                     xferbytes = recv(sockfd,
                                   buf->curpos, 
                                   buf->end - buf->curpos, 
                                   0);
                    if(xferbytes > 0)
                    {
                        buf->curpos = buf->curpos + xferbytes;
                    }
                    else
                    {
                        result =  SLP_NETWORK_ERROR;
                        break;
                    }
                }
                else if(xferbytes == 0)
                {
                    result = SLP_NETWORK_TIMED_OUT;
                    break;
                }
                else
                {
                    result =  SLP_NETWORK_ERROR;
                    break;
                }
            } /* end of main read while. */  
        }
        else
        {
            result = SLP_MEMORY_ALLOC_FAILED;
        }
    }
    else
    {
        result = SLP_PARSE_ERROR;
    }

    return result;
}