/*-------------------------------------------------------------------------*/ void HandleSocketListen(SLPDSocketList* list, SLPDSocket* sock) /*-------------------------------------------------------------------------*/ { SLPDSocket* connsock; /* check to see if we have accepted the maximum number of sockets */ if(list->count < SLPD_MAX_SOCKETS) { connsock = (SLPDSocket*) malloc(sizeof(SLPDSocket)); memset(connsock,0,sizeof(SLPDSocket)); connsock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr); connsock->fd = accept(sock->fd, &(connsock->peerinfo.peeraddr), &(connsock->peerinfo.peeraddrlen)); if(sock->fd >= 0) { /* TODO: do a getsockopt() to determine if local */ connsock->peerinfo.peertype = SLPD_PEER_REMOTE; connsock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); connsock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); connsock->state = STREAM_FIRST_READ; time(&(connsock->timestamp)); SLPDSocketListAdd(list,connsock); } else { free(connsock); } } }
/*=========================================================================*/ void SLPDSocketInit(SLPDSocketList* list) /* Adds SLPSockets (UDP and TCP) for all the interfaces and the loopback */ /* */ /* list - pointer to SLPSocketList to initialize */ /* */ /* Returns - zero on success, -1 on failure. */ /*=========================================================================*/ { char* begin; char* end; int finished; struct in_addr myaddr; struct in_addr mcastaddr; struct in_addr bcastaddr; SLPDSocket* sock; /*----------------------------------------------------*/ /* Decide what address to use for multicast/broadcast */ /*----------------------------------------------------*/ mcastaddr.s_addr = htonl(SLP_MCAST_ADDRESS); bcastaddr.s_addr = htonl(0xffffffff); /*-----------------------------------------------------------------*/ /* Create SOCKET_LISTEN socket for LOOPBACK for the library to talk to*/ /*-----------------------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { return; } memset(sock,0,sizeof(SLPDSocket)); sock->fd = socket(PF_INET, SOCK_STREAM, 0); if(sock->fd >= 0) { if(BindSocketToLoopback(sock->fd) >= 0) { if(listen(sock->fd,5) == 0) { sock->state = SOCKET_LISTEN; if(SLPDSocketListAdd(list,sock) == 0) { SLPFatal("Out of memory"); } SLPLog("SLPLIB API socket listening\n"); } else { /* could not listen(), close the socket*/ close(sock->fd); free(sock); SLPLog("ERROR: Could not listen on loopback\n"); SLPLog("ERROR: No SLPLIB support will be available\n"); } } else { /* could not bind, close the socket*/ close(sock->fd); free(sock); SLPLog("ERROR: Could not bind loopback port 427.\n"); SLPLog("ERROR: slpd may already be running\n"); } } else { /* could not create the socket */ free(sock); SLPLog("ERROR: Could not create socket for loopback.\n"); SLPLog("ERROR: No SLPLIB support will be available\n"); } /*---------------------------------------------------------------------*/ /* Create sockets for all of the interfaces in the interfaces property */ /*---------------------------------------------------------------------*/ begin = (char*)G_SlpdProperty.interfaces; end = begin; finished = 0; while( finished == 0) { while(*end && *end != ',') end ++; if(*end == 0) finished = 1; while(*end <=0x2f) { *end = 0; end--; } /* begin now points to a null terminated ip address string */ myaddr.s_addr = inet_addr(begin); /*--------------------------------------------------------*/ /* Create socket that will handle multicast UDP */ /*--------------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { break; } sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >=0) { if(BindSocketToInetAddr(sock->fd, &mcastaddr) >= 0) { if(JoinSLPMulticastGroup(sock->fd, &myaddr) == 0) { sock->state = DATAGRAM_MULTICAST; sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr); sock->peerinfo.peertype = SLPD_PEER_REMOTE; if(sock->recvbuf == 0 || sock->sendbuf == 0) { SLPFatal("SLPD out of memory !!\n"); } SLPDSocketListAdd(list,sock); SLPLog("Multicast socket on %s ready\n",inet_ntoa(myaddr)); } else { /* could not add multicast membership */ close(sock->fd); free(sock); } } else { /* could not bind(), close the socket*/ close(sock->fd); free(sock); } } /*--------------------------------------------*/ /* Create socket that will handle unicast UDP */ /*--------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { break; } sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >= 0) { if(BindSocketToInetAddr(sock->fd, &myaddr) >= 0) { sock->state = DATAGRAM_UNICAST; sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->peerinfo.peertype = SLPD_PEER_REMOTE; if(sock->recvbuf == 0 || sock->sendbuf == 0) { SLPFatal("SLPD out of memory !!\n"); } SLPDSocketListAdd(list,sock); SLPLog("UDP socket on %s ready\n",inet_ntoa(myaddr)); } else { /* could not bind(), close the socket*/ close(sock->fd); free(sock); } } /*------------------------------------------------*/ /* Create TCP_LISTEN that will handle unicast TCP */ /*------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { break; } sock->fd = socket(PF_INET, SOCK_STREAM, 0); if(sock->fd >= 0) { if(BindSocketToInetAddr(sock->fd, &myaddr) >= 0) { if(listen(sock->fd,2) == 0) { sock->state = SOCKET_LISTEN; if(SLPDSocketListAdd(list,sock) == 0) { SLPFatal("Out of memory"); } SLPLog("TCP socket on %s listening\n",inet_ntoa(myaddr)); } else { /* could not listen(), close the socket*/ close(sock->fd); free(sock); } } else { /* could not bind, close the socket*/ close(sock->fd); free(sock); } } begin = end + 1; } /*--------------------------------------------------------*/ /* Create socket that will handle broadcast UDP */ /*--------------------------------------------------------*/ sock = (SLPDSocket*)malloc(sizeof(SLPDSocket)); if(sock == 0) { return; } sock->fd = socket(PF_INET, SOCK_DGRAM, 0); if(sock->fd >=0) { if(BindSocketToInetAddr(sock->fd, &bcastaddr) >= 0) { if(EnableBroadcast(sock->fd) == 0) { sock->state = DATAGRAM_BROADCAST; sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE); sock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr); sock->peerinfo.peertype = SLPD_PEER_REMOTE; if(sock->recvbuf == 0 || sock->sendbuf == 0) { SLPFatal("SLPD out of memory !!\n"); } SLPDSocketListAdd(list,sock); SLPLog("Broadcast socket for %s ready\n", inet_ntoa(bcastaddr)); } else { /* could not add multicast membership */ close(sock->fd); free(sock); } } else { /* could not bind(), close the socket*/ close(sock->fd); free(sock); } } }
/*=========================================================================*/ void SLPDKnownDARegister(SLPDDatabaseEntry* dbhead, SLPDSocketList* sockets) /* */ /* Modify the specified socket list to register all entries of the */ /* specified database list with all known DAs */ /* */ /* Returns: Zero on success, non-zero on error */ /*=========================================================================*/ { SLPDDatabaseEntry* dbentry; SLPDSocket* sockentry; SLPDAEntry* daentry; if(dbhead) { daentry = G_KnownDAListHead; while(daentry) { /* check to see if a socket is already connected to this DA */ sockentry = sockets->head; while(sockentry) { if(sockentry->peerinfo.peertype == SLPD_PEER_CONNECTED) { if (memcmp(&sockentry->peerinfo.peeraddr.sin_addr, &daentry->daaddr, sizeof(daentry->daaddr)) == 0) { break; } } sockentry = (SLPDSocket*)sockentry->listitem.next; } if(sockentry == 0) { /* Could not find a connected socket */ /* Create a connected socket */ sockentry = SLPDSocketCreateConnected(&daentry->daaddr); if(sockentry == 0) { /* Could not create connected socket */ /* TODO: should we log here? */ /* Remove the known DA entry we could not connect to */ daentry = SLPDKnownDARemove(daentry); } else { SLPDSocketListAdd(sockets, sockentry); } } if(sockentry != 0) { /* Load the send buffer with reg stuff */ dbentry = dbhead; while(dbentry) { /* TODO: put a whole bunch of registration stuff here */ dbentry = (SLPDDatabaseEntry*)dbentry->listitem.next; } } daentry = (SLPDAEntry*)daentry->listitem.next; } } }