📄 slpd_knownda.c
字号:
/***************************************************************************//* *//* Project: OpenSLP - OpenSource implementation of Service Location *//* Protocol Version 2 *//* *//* File: slpd_knownda.c *//* *//* Abstract: Keeps track of known DAs *//* *//*-------------------------------------------------------------------------*//* *//* Please submit patches to http://www.openslp.org *//* *//*-------------------------------------------------------------------------*//* *//* Copyright (C) 2000 Caldera Systems, Inc *//* All rights reserved. *//* *//* Redistribution and use in source and binary forms, with or without *//* modification, are permitted provided that the following conditions are *//* met: */ /* *//* Redistributions of source code must retain the above copyright *//* notice, this list of conditions and the following disclaimer. *//* *//* Redistributions in binary form must reproduce the above copyright *//* notice, this list of conditions and the following disclaimer in *//* the documentation and/or other materials provided with the *//* distribution. *//* *//* Neither the name of Caldera Systems nor the names of its *//* contributors may be used to endorse or promote products derived *//* from this software without specific prior written permission. *//* *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* *//***************************************************************************/#include "slpd.h"/*=========================================================================*//* slpd includes *//*=========================================================================*/#include "slpd_knownda.h"#include "slpd_property.h"#include "slpd_database.h"#include "slpd_socket.h"#include "slpd_outgoing.h"#include "slpd_log.h"#ifdef ENABLE_SLPv2_SECURITY #include "slpd_spi.h"#endif/*=========================================================================*//* common code includes *//*=========================================================================*/#include "slp_xmalloc.h"#include "slp_v1message.h"#include "slp_utf8.h"#include "slp_compare.h"#include "slp_xid.h"#include "slp_dhcp.h"#include "slp_parse.h"#include "slp_net.h"#ifdef ENABLE_SLPv2_SECURITY #include "slp_auth.h" #include "slp_spi.h"#endif#include <limits.h>/*=========================================================================*/SLPDatabase G_SlpdKnownDAs;/* The database of DAAdverts from DAs known to slpd. *//*=========================================================================*//*=========================================================================*/int G_KnownDATimeSinceLastRefresh = 0;/*=========================================================================*//*-------------------------------------------------------------------------*/int MakeActiveDiscoveryRqst(int ismcast, SLPBuffer* buffer)/* Pack a buffer with service:directory-agent SrvRqst * * * * Caller must free buffer * *-------------------------------------------------------------------------*/{ size_t size; void* eh; SLPMessage msg; char* prlist = 0; size_t prlistlen = 0; int errorcode = 0; SLPBuffer tmp = 0; SLPBuffer result = *buffer; /*-------------------------------------------------*/ /* Generate a DA service request buffer to be sent */ /*-------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ size = 47; /* 14 bytes for the header */ /* 2 bytes for the prlistlen */ /* 2 bytes for the srvtype length */ /* 23 bytes for "service:directory-agent" srvtype */ /* 2 bytes for scopelistlen */ /* 2 bytes for predicatelen */ /* 2 bytes for sprstrlen */ /* figure out what our Prlist will be by going through our list of */ /* known DAs */ prlistlen = 0; prlist = xmalloc(SLP_MAX_DATAGRAM_SIZE); if ( prlist == 0 ) { /* out of memory */ errorcode = SLP_ERROR_INTERNAL_ERROR; goto FINISHED; } *prlist = 0; /* Don't send active discoveries to DAs we already know about */ eh = SLPDKnownDAEnumStart(); if ( eh ) { while ( 1 ) { if ( SLPDKnownDAEnum(eh, &msg, &tmp) == 0 ) { break; } strcat(prlist,inet_ntoa(msg->peer.sin_addr)); strcat(prlist,","); prlistlen = strlen(prlist); } SLPDKnownDAEnumEnd(eh); } /* Allocate the send buffer */ size += G_SlpdProperty.localeLen + prlistlen; result = SLPBufferRealloc(result, size); if ( result == 0 ) { /* out of memory */ errorcode = SLP_ERROR_INTERNAL_ERROR; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /*version*/ *(result->start) = 2; /*function id*/ *(result->start + 1) = SLP_FUNCT_SRVRQST; /*length*/ ToUINT24(result->start + 2, size); /*flags*/ ToUINT16(result->start + 5, (ismcast ? SLP_FLAG_MCAST : 0)); /*ext offset*/ ToUINT24(result->start + 7,0); /*xid*/ ToUINT16(result->start + 10, SLPXidGenerate()); /* TODO: generate a real XID */ /*lang tag len*/ ToUINT16(result->start + 12, G_SlpdProperty.localeLen); /*lang tag*/ memcpy(result->start + 14, G_SlpdProperty.locale, G_SlpdProperty.localeLen); result->curpos = result->start + G_SlpdProperty.localeLen + 14; /* Prlist */ ToUINT16(result->curpos,prlistlen); result->curpos = result->curpos + 2; memcpy(result->curpos,prlist,prlistlen); result->curpos = result->curpos + prlistlen; /* service type */ ToUINT16(result->curpos,23); result->curpos = result->curpos + 2; /* 23 is the length of SLP_DA_SERVICE_TYPE */ memcpy(result->curpos,SLP_DA_SERVICE_TYPE,23); result->curpos = result->curpos + 23; /* scope list zero length */ ToUINT16(result->curpos,0); result->curpos = result->curpos + 2; /* predicate zero length */ ToUINT16(result->curpos,0); result->curpos = result->curpos + 2; /* spi list zero length */ ToUINT16(result->curpos,0); result->curpos = result->curpos + 2; *buffer = result; FINISHED: if ( prlist ) { xfree(prlist); } return 0;}/*-------------------------------------------------------------------------*/void SLPDKnownDARegisterAll(SLPMessage daadvert, int immortalonly)/* registers all services with specified DA *//*-------------------------------------------------------------------------*/{ SLPBuffer buf; SLPMessage msg; SLPSrvReg* srvreg; SLPDSocket* sock; SLPBuffer sendbuf = 0; void* handle = 0; /*---------------------------------------------------------------*/ /* Check to see if the database is empty and open an enumeration */ /* handle if it is not empty */ /*---------------------------------------------------------------*/ if ( SLPDDatabaseIsEmpty() ) { return; } /*--------------------------------------*/ /* Never do a Register All to ourselves */ /*--------------------------------------*/ if ( SLPCompareString(G_SlpdProperty.myUrlLen, G_SlpdProperty.myUrl, daadvert->body.daadvert.urllen, daadvert->body.daadvert.url) == 0 ) { return; } handle = SLPDDatabaseEnumStart(); if ( handle == 0 ) { return; } /*----------------------------------------------*/ /* Establish a new connection with the known DA */ /*----------------------------------------------*/ sock = SLPDOutgoingConnect(&(daadvert->peer.sin_addr)); if ( sock ) { while ( 1 ) { msg = SLPDDatabaseEnum(handle, &msg, &buf); if ( msg == NULL ) break; srvreg = &(msg->body.srvreg); /*-----------------------------------------------*/ /* If so instructed, skip mortal registrations */ /*-----------------------------------------------*/ if ( immortalonly && srvreg->urlentry.lifetime < SLP_LIFETIME_MAXIMUM ) { continue; } /*---------------------------------------------------------*/ /* Only register local (or static) registrations of scopes */ /* supported by peer DA */ /*---------------------------------------------------------*/ if ( ( srvreg->source == SLP_REG_SOURCE_LOCAL || srvreg->source == SLP_REG_SOURCE_STATIC ) && SLPIntersectStringList(srvreg->scopelistlen, srvreg->scopelist, srvreg->scopelistlen, srvreg->scopelist) ) { sendbuf = SLPBufferDup(buf); if ( sendbuf ) { /*--------------------------------------------------*/ /* link newly constructed buffer to socket sendlist */ /*--------------------------------------------------*/ SLPListLinkTail(&(sock->sendlist),(SLPListItem*)sendbuf); if ( sock->state == STREAM_CONNECT_IDLE ) { sock->state = STREAM_WRITE_FIRST; } } } } } SLPDDatabaseEnumEnd(handle);} /*-------------------------------------------------------------------------*/int MakeSrvderegFromSrvReg(SLPMessage msg, SLPBuffer inbuf, SLPBuffer* outbuf)/* Pack a buffer with a SrvDereg message using information from an existing * SrvReg message * * Caller must free outbuf *-------------------------------------------------------------------------*/{ int size; SLPBuffer sendbuf; SLPSrvReg* srvreg; srvreg = &(msg->body.srvreg); /*-------------------------------------------------------------*/ /* ensure the buffer is big enough to handle the whole srvdereg*/ /*-------------------------------------------------------------*/ size = msg->header.langtaglen + 18; /* 14 bytes for header */ /* 2 bytes for scopelen */ /* see below for URLEntry */ /* 2 bytes for taglist len */ if ( srvreg->urlentry.opaque ) { size += srvreg->urlentry.opaquelen; } else { size += 6; /* +6 for the static portion of the url-entry */ size += srvreg->urlentry.urllen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -