📄 libslp_knownda.c
字号:
/***************************************************************************//* *//* Project: OpenSLP - OpenSource implementation of Service Location *//* Protocol *//* *//* File: libslp_knownda.c *//* *//* Abstract: Internal implementation for generating unique XIDs. *//* Provides functions that are supposed to generate 16-bit *//* values that won't be generated for a long time in this *//* process and hopefully won't be generated by other process */ /* for a long time. *//* *//*-------------------------------------------------------------------------*//* *//* 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 "slp.h"#include "libslp.h"#include "slp_dhcp.h"#ifndef _WIN32#define closesocket close#endif#include <time.h>/*=========================================================================*/SLPDatabase G_KnownDACache ={0,0,0};/* The cache DAAdvert messages from known DAs. *//*=========================================================================*//*=========================================================================*/int G_KnownDAScopesLen = 0;char* G_KnownDAScopes = 0;/* Cached known scope list *//*=========================================================================*//*=========================================================================*/time_t G_KnownDALastCacheRefresh = 0;/* The time of the last Multicast for known DAs *//*=========================================================================*//*-------------------------------------------------------------------------*/SLPBoolean KnownDAListFind(int scopelistlen, const char* scopelist, int spistrlen, const char* spistr, struct in_addr* daaddr)/* Returns: non-zero on success, zero if DA can not be found *//*-------------------------------------------------------------------------*/{ SLPDatabaseHandle dh; SLPDatabaseEntry* entry; int result = SLP_FALSE; dh = SLPDatabaseOpen(&G_KnownDACache); if(dh) { /*----------------------------------------*/ /* Check to see if there a matching entry */ /*----------------------------------------*/ while(1) { entry = SLPDatabaseEnum(dh); if(entry == NULL) break; /* Check scopes */ if(SLPSubsetStringList(entry->msg->body.daadvert.scopelistlen, entry->msg->body.daadvert.scopelist, scopelistlen, scopelist)) {#ifdef ENABLE_SLPv2_SECURITY if(SLPCompareString(entry->msg->body.daadvert.spilistlen, entry->msg->body.daadvert.spilist, spistrlen, spistr) == 0)#endif { memcpy(daaddr, &(entry->msg->peer.sin_addr), sizeof(struct in_addr)); result = SLP_TRUE; } } } SLPDatabaseClose(dh); } return result;}/*-------------------------------------------------------------------------*/int KnownDAAdd(SLPMessage msg, SLPBuffer buf)/* Add an entry to the KnownDA cache *//* *//* Returns: zero on success, non-zero on error *//*-------------------------------------------------------------------------*/{ SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPDAAdvert* entrydaadvert; SLPDAAdvert* daadvert; int result; result = 0; dh = SLPDatabaseOpen(&G_KnownDACache); if(dh) { /* daadvert is the DAAdvert message being added */ daadvert = &(msg->body.daadvert); /*-----------------------------------------------------*/ /* Check to see if there is already an identical entry */ /*-----------------------------------------------------*/ while(1) { entry = SLPDatabaseEnum(dh); if(entry == NULL) break; /* entrydaadvert is the DAAdvert message from the database */ entrydaadvert = &(entry->msg->body.daadvert); /* Assume DAs are identical if their URLs match */ if(SLPCompareString(entrydaadvert->urllen, entrydaadvert->url, daadvert->urllen, daadvert->url) == 0) { SLPDatabaseRemove(dh,entry); break; } } /* Create and link in a new entry */ entry = SLPDatabaseEntryCreate(msg,buf); if(entry) { SLPDatabaseAdd(dh, entry); } else { result = SLP_MEMORY_ALLOC_FAILED; } SLPDatabaseClose(dh); } return result;}/*-------------------------------------------------------------------------*/SLPBoolean KnownDADiscoveryCallback(SLPError errorcode, struct sockaddr_in* peerinfo, SLPBuffer rplybuf, void* cookie)/*-------------------------------------------------------------------------*/{ SLPMessage replymsg; SLPBuffer dupbuf; struct hostent* he; SLPSrvURL* srvurl; int* count; SLPBoolean result = SLP_TRUE; count = (int*)cookie; if(errorcode == 0) { dupbuf = SLPBufferDup(rplybuf); if(dupbuf) { replymsg = SLPMessageAlloc(); if(replymsg) { if(SLPMessageParseBuffer(peerinfo,dupbuf,replymsg) == 0 && replymsg->header.functionid == SLP_FUNCT_DAADVERT) { if(replymsg->body.daadvert.errorcode == 0) { /* TRICKY: NULL terminate the DA url */ ((char*)(replymsg->body.daadvert.url))[replymsg->body.daadvert.urllen] = 0; if(SLPParseSrvURL(replymsg->body.daadvert.url, &srvurl) == 0) { replymsg->peer.sin_addr.s_addr = 0; if(inet_aton(srvurl->s_pcHost, &(replymsg->peer.sin_addr)) == 0) { he = gethostbyname(srvurl->s_pcHost); if(he) { /* Reset the peer to the one in the URL */ replymsg->peer.sin_addr.s_addr = *((unsigned int*)(he->h_addr_list[0])); } } SLPFree(srvurl); if(replymsg->peer.sin_addr.s_addr) { (*count) += 1; KnownDAAdd(replymsg,dupbuf); if(replymsg->header.flags & SLP_FLAG_MCAST) { return SLP_FALSE; } return SLP_TRUE; } } } else if(replymsg->body.daadvert.errorcode == SLP_ERROR_INTERNAL_ERROR) { /* SLP_ERROR_INTERNAL_ERROR is a "end of stream" */ /* marker for looppack IPC */ result = SLP_FALSE; } } SLPMessageFree(replymsg); } SLPBufferFree(dupbuf); } } return result;} /*-------------------------------------------------------------------------*/int KnownDADiscoveryRqstRply(int sock, struct sockaddr_in* peeraddr, int scopelistlen,#ifndef MI_NOT_SUPPORTED const char* scopelist, PSLPHandleInfo handle)#else const char* scopelist)#endif /* MI_NOT_SUPPORTED *//* Returns: number of *new* DAEntries found *//*-------------------------------------------------------------------------*/{ char* buf; char* curpos; int bufsize; int result = 0; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = 31; /* 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 */ bufsize += scopelistlen; /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { return 0; } memset(buf,0,bufsize); /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,23); curpos = curpos + 2; /* 23 is the length of SLP_DA_SERVICE_TYPE */ memcpy(curpos,SLP_DA_SERVICE_TYPE,23); curpos += 23; /* scope list */ ToUINT16(curpos,scopelistlen); curpos = curpos + 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -