You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
16 KiB

/***************************************************************************/
/* */
/* Project: OpenSLP - OpenSource implementation of Service Location */
/* Protocol */
/* */
/* File: slplib_handle.h */
/* */
/* Abstract: Implementation for SLPOpen() and SLPClose() functions */
/* */
/*-------------------------------------------------------------------------*/
/* */
/* 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"
/*=========================================================================*/
int G_OpenSLPHandleCount = 0;
/* Global variable that keeps track of the number of handles that are open */
/*=========================================================================*/
/*=========================================================================*/
SLPError SLPAPI SLPOpen(const char *pcLang, SLPBoolean isAsync, SLPHandle *phSLP)
/* */
/* Returns a SLPHandle handle in the phSLP parameter for the language */
/* locale passed in as the pcLang parameter. The client indicates if */
/* operations on the handle are to be synchronous or asynchronous */
/* through the isAsync parameter. The handle encapsulates the language */
/* locale for SLP requests issued through the handle, and any other */
/* resources required by the implementation. However, SLP properties */
/* are not encapsulated by the handle; they are global. The return */
/* value of the function is an SLPError code indicating the status of */
/* the operation. Upon failure, the phSLP parameter is NULL. */
/* */
/* An SLPHandle can only be used for one SLP API operation at a time. */
/* If the original operation was started asynchronously, any attempt to */
/* start an additional operation on the handle while the original */
/* operation is pending results in the return of an SLP_HANDLE_IN_USE */
/* error from the API function. The SLPClose() API function terminates */
/* any outstanding calls on the handle. If an implementation is unable */
/* to support a asynchronous( resp. synchronous) operation, due to */
/* memory constraints or lack of threading support, the */
/* SLP_NOT_IMPLEMENTED flag may be returned when the isAsync flag is */
/* SLP_TRUE (resp. SLP_FALSE). */
/* */
/* pcLang A pointer to an array of characters containing the RFC 1766 */
/* Language Tag RFC 1766 for the natural language locale of */
/* requests and registrations issued on the handle. Pass in NULL */
/* or the empty string, "" to use the default locale */
/* */
/* isAsync An SLPBoolean indicating whether the SLPHandle should be opened*/
/* for asynchronous operation or not. */
/* */
/* phSLP A pointer to an SLPHandle, in which the open SLPHandle is */
/* returned. If an error occurs, the value upon return is NULL. */
/* */
/* Returns SLPError code */
/*=========================================================================*/
{
SLPError result = SLP_OK;
PSLPHandleInfo handle = 0;
/*------------------------------*/
/* check for invalid parameters */
/*------------------------------*/
if(phSLP == 0)
{
result = SLP_PARAMETER_BAD;
goto FINISHED;
}
/* assign out param to zero in just for paranoia */
*phSLP = 0;
#ifndef ENABLE_ASYNC_API
if(isAsync == SLP_TRUE)
{
result = SLP_NOT_IMPLEMENTED;
goto FINISHED;
}
/*-------------------------------------------------------*/
/* TODO: remove the #else when we implement async calls */
/*-------------------------------------------------------*/
#else
if(isAsync == SLP_TRUE)
{
result = SLP_NOT_IMPLEMENTED;
goto FINISHED;
}
#endif
/*------------------------------------*/
/* allocate a SLPHandleInfo structure */
/*------------------------------------*/
handle = (PSLPHandleInfo)xmalloc(sizeof(SLPHandleInfo));
if(handle == 0)
{
result = SLP_PARAMETER_BAD;
goto FINISHED;
}
memset(handle,0,sizeof(SLPHandleInfo));
/*-------------------------------*/
/* Set the language tag */
/*-------------------------------*/
if(pcLang && *pcLang)
{
handle->langtaglen = strlen(pcLang);
handle->langtag = (char*)xmalloc(handle->langtaglen + 1);
if(handle->langtag == 0)
{
xfree(handle);
result = SLP_PARAMETER_BAD;
goto FINISHED;
}
memcpy(handle->langtag,pcLang,handle->langtaglen + 1);
}
else
{
handle->langtaglen = strlen(SLPGetProperty("net.slp.locale"));
handle->langtag = (char*)xmalloc(handle->langtaglen + 1);
if(handle->langtag == 0)
{
xfree(handle);
result = SLP_PARAMETER_BAD;
goto FINISHED;
}
memcpy(handle->langtag,SLPGetProperty("net.slp.locale"),handle->langtaglen + 1);
}
/*---------------------------------------------------------*/
/* Seed the XID generator if this is the first open handle */
/*---------------------------------------------------------*/
if(G_OpenSLPHandleCount == 0)
{
#ifdef _WIN32
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1,1);
if(0 != WSAStartup(wVersionRequested, &wsaData))
{
result = SLP_NETWORK_INIT_FAILED;
goto FINISHED;
}
#endif
#ifdef DEBUG
xmalloc_init("/tmp/libslp_xmalloc.log",0);
#endif
SLPXidSeed();
}
#ifdef ENABLE_SLPv2_SECURITY
handle->hspi = SLPSpiOpen(LIBSLP_SPIFILE,0);
#endif
handle->sig = SLP_HANDLE_SIG;
handle->inUse = SLP_FALSE;
handle->isAsync = isAsync;
handle->dasock = -1;
handle->sasock = -1;
#ifndef UNICAST_NOT_SUPPORTED
handle->unicastsock = -1;
#endif
G_OpenSLPHandleCount ++;
*phSLP = (SLPHandle)handle;
FINISHED:
if(result)
{
*phSLP = 0;
}
return result;
}
/*=========================================================================*/
void SLPAPI SLPClose(SLPHandle hSLP)
/* */
/* Frees all resources associated with the handle. If the handle was */
/* invalid, the function returns silently. Any outstanding synchronous */
/* or asynchronous operations are cancelled so their callback functions */
/* will not be called any further. */
/* */
/* SLPHandle A SLPHandle handle returned from a call to SLPOpen(). */
/*=========================================================================*/
{
PSLPHandleInfo handle;
/*------------------------------*/
/* check for invalid parameters */
/*------------------------------*/
if(hSLP == 0 || *(unsigned int*)hSLP != SLP_HANDLE_SIG)
{
return;
}
handle = (PSLPHandleInfo)hSLP;
if(handle->isAsync)
{
/* TODO: stop the usage of this handle (kill threads, etc) */
}
if(handle->langtag)
{
xfree(handle->langtag);
}
if(handle->dasock >=0)
{
#ifdef _WIN32
closesocket(handle->dasock);
#else
close(handle->dasock);
#endif
}
if(handle->dascope)
{
xfree(handle->dascope);
}
if(handle->sasock >=0)
{
#ifdef _WIN32
closesocket(handle->sasock);
#else
close(handle->sasock);
#endif
}
if(handle->sascope)
{
xfree(handle->sascope);
}
#ifdef ENABLE_SLPv2_SECURITY
if(handle->hspi) SLPSpiClose(handle->hspi);
#endif
handle->sig = 0; /* If they use the handle again, it won't be valid */
xfree(hSLP);
G_OpenSLPHandleCount --;
#if DEBUG
/* Free additional resources if this is the last handle open */
if(G_OpenSLPHandleCount <= 0)
{
G_OpenSLPHandleCount = 0;
SLPPropertyFreeAll();
KnownDAFreeAll();
xmalloc_deinit();
}
#endif
}
#ifndef MI_NOT_SUPPORTED
/*=========================================================================*/
SLPError SLPAssociateIFList( SLPHandle hSLP, const char* McastIFList)
/* */
/* Associates a list of interfaces McastIFList on which multicast needs to */
/* be done with a particular SLPHandle hSLP. McastIFList is a comma */
/* separated list of host interface IP addresses. */
/* */
/* hSLP The SLPHandle with which the interface list is to */
/* be associated with. */
/* */
/* McastIFList A comma separated list of host interface IP */
/* addresses on which multicast needs to be done. */
/* */
/* Returns SLPError code */
/*=========================================================================*/
{
PSLPHandleInfo handle;
/*------------------------------*/
/* check for invalid parameters */
/*------------------------------*/
if(hSLP == 0 ||
*(unsigned int*)hSLP != SLP_HANDLE_SIG ||
McastIFList == 0 ||
*McastIFList == 0) /* interface list can't be empty string */
{
return SLP_PARAMETER_BAD;
}
handle = (PSLPHandleInfo)hSLP;
#ifdef DEBUG
fprintf(stderr, "SLPAssociateIFList(): McastIFList = %s\n", McastIFList);
#endif
handle->McastIFList = McastIFList;
return SLP_OK;
}
#endif /* MI_NOT_SUPPORTED */
#ifndef UNICAST_NOT_SUPPORTED
/*=========================================================================*/
SLPError SLPAssociateIP( SLPHandle hSLP, const char* unicast_ip)
/* */
/* Associates an IP address unicast_ip with a particular SLPHandle hSLP. */
/* unicast_ip is the IP address of the SA/DA from which service is */
/* requested. */
/* */
/* hSLP The SLPHandle with which the unicast_ip address is */
/* to be associated with. */
/* */
/* unicast_ip IP address of the SA/DA from which service is */
/* requested. */
/* */
/* Returns SLPError code */
/*=========================================================================*/
{
PSLPHandleInfo handle;
/*------------------------------*/
/* check for invalid parameters */
/*------------------------------*/
if(hSLP == 0 ||
*(unsigned int*)hSLP != SLP_HANDLE_SIG ||
unicast_ip == 0 ||
*unicast_ip == 0) /* unicast address not specified */
{
return SLP_PARAMETER_BAD;
}
handle = (PSLPHandleInfo)hSLP;
#ifdef DEBUG
fprintf(stderr, "SLPAssociateIP(): unicast_ip = %s\n", unicast_ip);
#endif
handle->dounicast = 1;
handle->unicastaddr.sin_family = AF_INET;
if (inet_aton(unicast_ip, ((struct in_addr *)(&handle->unicastaddr.sin_addr))) == 0 )
{
return SLP_PARAMETER_BAD;
}
handle->unicastaddr.sin_port = htons(SLP_RESERVED_PORT);
return SLP_OK;
}
#endif