/*-------------------------------------------------------------------------*/ int KnownDADiscoveryByMulticast() /* Locates DAs via multicast convergence */ /* */ /* Returns The number of DAs found */ /*-------------------------------------------------------------------------*/ { int result = 0; int sock; struct sockaddr_in peeraddr; sock = NetworkConnectToMulticast(&peeraddr); if(sock >= 0) { result = KnownDADiscoveryRqstRply(sock, &peeraddr); close(sock); } return result;; }
/*-------------------------------------------------------------------------*/ int KnownDADiscoverFromMulticast(int scopelistlen, const char* scopelist) /* Locates DAs via multicast convergence */ /* */ /* Returns: number of *new* DAs found */ /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sockfd; int result = 0; sockfd = NetworkConnectToMulticast(&peeraddr); if(sockfd >= 0) { result = KnownDADiscoveryRqstRply(sockfd, &peeraddr, scopelistlen, scopelist); close(sockfd); } return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sock = 0; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findsrvs.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.predicatelen + 2; /* 2 bytes for len field */ bufsize += 2; /* 2 bytes for spistr len*/ /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)malloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,handle->params.findsrvs.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.srvtype, handle->params.findsrvs.srvtypelen); curpos = curpos + handle->params.findsrvs.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.findsrvs.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen); curpos = curpos + handle->params.findsrvs.scopelistlen; /* predicate */ ToUINT16(curpos,handle->params.findsrvs.predicatelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.predicate, handle->params.findsrvs.predicatelen); curpos = curpos + handle->params.findsrvs.predicatelen; /* TODO: add spi list stuff here later*/ ToUINT16(curpos,0); /*---------------------------------------*/ /* Connect to DA, multicast or broadcast */ /*---------------------------------------*/ sock = NetworkConnectToDA(handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); if(sock < 0) { sock = NetworkConnectToMulticast(&peeraddr); if(sock < 0) { result = SLP_NETWORK_INIT_FAILED; goto FINISHED; } } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVRQST, bufsize, CallbackSrvRqst, handle); FINISHED: if(buf) free(buf); return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { struct sockaddr_in peeraddr; int sock = -1; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; #ifdef ENABLE_SLPv2_SECURITY int spistrlen = 0; char* spistr = 0; #endif /*------------------------------------------*/ /* Is this a special attempt to locate DAs? */ /*------------------------------------------*/ if(strncasecmp(handle->params.findsrvs.srvtype, SLP_DA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen) == 0) { KnownDAProcessSrvRqst(handle); goto FINISHED; } #ifdef ENABLE_SLPv2_SECURITY if(SLPPropertyAsBoolean(SLPGetProperty("net.slp.securityEnabled"))) { SLPSpiGetDefaultSPI(handle->hspi, SLPSPI_KEY_TYPE_PUBLIC, &spistrlen, &spistr); } #endif /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVRQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findsrvs.srvtypelen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.scopelistlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvs.predicatelen + 2; /* 2 bytes for len field */ bufsize += 2; /* 2 bytes for spistr len*/ #ifdef ENABLE_SLPv2_SECURITY bufsize += spistrlen; #endif buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVRQST */ /*------------------------------------------------------------*/ /* service type */ ToUINT16(curpos,handle->params.findsrvs.srvtypelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.srvtype, handle->params.findsrvs.srvtypelen); curpos = curpos + handle->params.findsrvs.srvtypelen; /* scope list */ ToUINT16(curpos,handle->params.findsrvs.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen); curpos = curpos + handle->params.findsrvs.scopelistlen; /* predicate */ ToUINT16(curpos,handle->params.findsrvs.predicatelen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvs.predicate, handle->params.findsrvs.predicatelen); curpos = curpos + handle->params.findsrvs.predicatelen; #ifdef ENABLE_SLPv2_SECURITY ToUINT16(curpos,spistrlen); curpos = curpos + 2; memcpy(curpos,spistr,spistrlen); curpos = curpos + spistrlen; #else ToUINT16(curpos,0); #endif /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { if(strncasecmp(handle->params.findsrvs.srvtype, SLP_SA_SERVICE_TYPE, handle->params.findsrvs.srvtypelen)) { sock = NetworkConnectToDA(handle, handle->params.findsrvs.scopelist, handle->params.findsrvs.scopelistlen, &peeraddr); } if(sock == -1) { /* use multicast as a last resort */ sock = NetworkConnectToMulticast(&peeraddr); result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, handle); /* close the socket */ #ifdef WIN32 closesocket(sock); #else close(sock); #endif break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVRQST, bufsize, ProcessSrvRplyCallback, handle); if(result) { NetworkDisconnectDA(handle); } }while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); #ifdef ENABLE_SLPv2_SECURITY if(spistr) xfree(spistr); #endif return result; }
/*-------------------------------------------------------------------------*/ SLPError ProcessSrvTypeRqst(PSLPHandleInfo handle) /*-------------------------------------------------------------------------*/ { int sock; struct sockaddr_in peeraddr; int bufsize = 0; char* buf = 0; char* curpos = 0; SLPError result = 0; /*-------------------------------------------------------------------*/ /* determine the size of the fixed portion of the SRVTYPERQST */ /*-------------------------------------------------------------------*/ bufsize = handle->params.findsrvtypes.namingauthlen + 2; /* 2 bytes for len field */ bufsize += handle->params.findsrvtypes.scopelistlen + 2; /* 2 bytes for len field */ /* TODO: make sure that we don't exceed the MTU */ buf = curpos = (char*)xmalloc(bufsize); if(buf == 0) { result = SLP_MEMORY_ALLOC_FAILED; goto FINISHED; } /*----------------------------------------------------------------*/ /* Build a buffer containing the fixed portion of the SRVTYPERQST */ /*----------------------------------------------------------------*/ /* naming authority */ if(strcmp(handle->params.findsrvtypes.namingauth, "*") == 0) { ToUINT16(curpos,0xffff); /* 0xffff indicates all service types */ curpos += 2; bufsize--; /* '*' is not put on the wire */ } else { ToUINT16(curpos,handle->params.findsrvtypes.namingauthlen); curpos += 2; memcpy(curpos, handle->params.findsrvtypes.namingauth, handle->params.findsrvtypes.namingauthlen); curpos += handle->params.findsrvtypes.namingauthlen; } /* scope list */ ToUINT16(curpos,handle->params.findsrvtypes.scopelistlen); curpos = curpos + 2; memcpy(curpos, handle->params.findsrvtypes.scopelist, handle->params.findsrvtypes.scopelistlen); curpos = curpos + handle->params.findsrvtypes.scopelistlen; /*--------------------------*/ /* Call the RqstRply engine */ /*--------------------------*/ do { sock = NetworkConnectToDA(handle, handle->params.findsrvtypes.scopelist, handle->params.findsrvtypes.scopelistlen, &peeraddr); if(sock == -1) { /* use multicast as a last resort */ sock = NetworkConnectToMulticast(&peeraddr); result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVTYPERQST, bufsize, ProcessSrvTypeRplyCallback, handle); #ifdef WIN32 closesocket(sock); #else close(sock); #endif break; } result = NetworkRqstRply(sock, &peeraddr, handle->langtag, buf, SLP_FUNCT_SRVTYPERQST, bufsize, ProcessSrvTypeRplyCallback, handle); if(result) { NetworkDisconnectDA(handle); } } while(result == SLP_NETWORK_ERROR); FINISHED: if(buf) xfree(buf); return result; }