diff options
Diffstat (limited to 'kdm/backend/socket.c')
-rw-r--r-- | kdm/backend/socket.c | 418 |
1 files changed, 0 insertions, 418 deletions
diff --git a/kdm/backend/socket.c b/kdm/backend/socket.c deleted file mode 100644 index 677a3d32f..000000000 --- a/kdm/backend/socket.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - -Copyright 1988, 1998 The Open Group -Copyright 2002 Sun Microsystems, Inc. All rights reserved. -Copyright 2002,2004 Oswald Buddenhagen <ossi@kde.org> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * socket.c - Support for BSD sockets - */ - -#include "dm.h" - -#if defined(XDMCP) && !defined(STREAMSCONN) - -#include "dm_error.h" -#include "dm_socket.h" - -#include <netdb.h> -#include <arpa/inet.h> - -static int c_request_port; - -static int -CreateListeningSocket( struct sockaddr *sock_addr, int salen ) -{ - int fd; -#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - int on = 0; -#endif - const char *addrstring = "unknown"; -#if defined(IPv6) && defined(AF_INET6) - char addrbuf[INET6_ADDRSTRLEN]; -#endif - - if (!request_port) - return -1; - - if (debugLevel & DEBUG_CORE) { -#if defined(IPv6) && defined(AF_INET6) - void *ipaddr; - if (sock_addr->sa_family == AF_INET6) - ipaddr = & ((struct sockaddr_in6 *)sock_addr)->sin6_addr; - else - ipaddr = & ((struct sockaddr_in *)sock_addr)->sin_addr; - addrstring = - inet_ntop( sock_addr->sa_family, ipaddr, addrbuf, sizeof(addrbuf) ); - -#else - addrstring = inet_ntoa( ((struct sockaddr_in *)sock_addr)->sin_addr ); -#endif - - Debug( "creating socket to listen on port %d of address %s\n", - request_port, addrstring ); - } - - if ((fd = socket( sock_addr->sa_family, SOCK_DGRAM, 0 )) == -1) { - LogError( "XDMCP socket creation failed, errno %d\n", errno ); - return -1; - } -#if defined(IPv6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) - setsockopt( fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on) ); -#endif - - if (bind( fd, sock_addr, salen ) == -1) { - LogError( "error %d binding socket address %d\n", errno, request_port ); - close( fd ); - return -1; - } - - RegisterCloseOnFork( fd ); - RegisterInput( fd ); - return fd; -} - -struct socklist { - struct socklist *next; - struct socklist *mcastgroups; - struct sockaddr *addr; - int salen; - int addrlen; - int fd; - int ref; /* referenced bit - see UpdateListenSockets */ -}; - -static struct socklist *listensocks; - -static void -DestroyListeningSocket( struct socklist *s ) -{ - struct socklist *g, *n; - - if (s->fd >= 0) { - CloseNClearCloseOnFork( s->fd ); - UnregisterInput( s->fd ); - s->fd = -1; - } - if (s->addr) { - free( s->addr ); - s->addr = NULL; - } - for (g = s->mcastgroups; g; g = n) { - n = g->next; - if (g->addr) - free( g->addr ); - free( g ); - } - s->mcastgroups = NULL; -} - -static struct socklist* -FindInList( struct socklist *list, ARRAY8Ptr addr ) -{ - struct socklist *s; - - for (s = list; s; s = s->next) { - if (s->addrlen == addr->length) { - char *addrdata; - - switch (s->addr->sa_family) { - case AF_INET: - addrdata = (char *) - &(((struct sockaddr_in *)s->addr)->sin_addr.s_addr); - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - addrdata = (char *) - &(((struct sockaddr_in6 *)s->addr)->sin6_addr.s6_addr); - break; -#endif - default: - /* Unrecognized address family */ - continue; - } - if (!memcmp( addrdata, addr->data, addr->length )) - return s; - } - } - return NULL; -} - -static struct socklist * -CreateSocklistEntry( ARRAY8Ptr addr ) -{ - struct socklist *s; - - if (!(s = Calloc( 1, sizeof(struct socklist) ))) - return NULL; - - if (addr->length == 4) { /* IPv4 */ - struct sockaddr_in *sin4; - sin4 = Calloc( 1, sizeof(struct sockaddr_in) ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin4->sin_len = sizeof(struct sockaddr_in); -#endif - s->addr = (struct sockaddr *)sin4; - s->salen = sizeof(struct sockaddr_in); - s->addrlen = sizeof(struct in_addr); - sin4->sin_family = AF_INET; - sin4->sin_port = htons( (short)request_port ); - memcpy( &sin4->sin_addr, addr->data, addr->length ); - } -#if defined(IPv6) && defined(AF_INET6) - else if (addr->length == 16) { /* IPv6 */ - struct sockaddr_in6 *sin6; - sin6 = Calloc( 1, sizeof(struct sockaddr_in6) ); -#ifdef SIN6_LEN - sin6->sin6_len = sizeof(struct sockaddr_in6); -#endif - s->addr = (struct sockaddr *)sin6; - s->salen = sizeof(struct sockaddr_in6); - s->addrlen = sizeof(struct in6_addr); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = htons( (short)request_port ); - memcpy( &sin6->sin6_addr, addr->data, addr->length ); - } -#endif - else { - /* Unknown address type */ - free( s ); - s = NULL; - } - return s; -} - -static void -UpdateListener( ARRAY8Ptr addr, void **closure ) -{ - struct socklist *s; - - *closure = NULL; - - if (addr == NULL) { - ARRAY8 tmpaddr; - struct in_addr in; -#if defined(IPv6) && defined(AF_INET6) - struct in6_addr in6 = in6addr_any; - tmpaddr.length = sizeof(in6); - tmpaddr.data = (CARD8Ptr) &in6; - UpdateListener( &tmpaddr, closure ); - if (*closure) - return; -#endif - in.s_addr = htonl( INADDR_ANY ); - tmpaddr.length = sizeof(in); - tmpaddr.data = (CARD8Ptr) ∈ - UpdateListener( &tmpaddr, closure ); - return; - } - - if (c_request_port == request_port && - (s = FindInList( listensocks, addr ))) - { - *closure = (void *)s; - s->ref = 1; - return; - } - - if (!(s = CreateSocklistEntry( addr ))) - return; - - if ((s->fd = CreateListeningSocket( s->addr, s->salen )) < 0) { - free( s->addr ); - free( s ); - return; - } - s->ref = 1; - s->next = listensocks; - listensocks = s; - *closure = (void *)s; -} - -#define JOIN_MCAST_GROUP 0 -#define LEAVE_MCAST_GROUP 1 - -static void -ChangeMcastMembership( struct socklist *s, struct socklist *g, int op ) -{ - int sockopt; - - switch (s->addr->sa_family) - { - case AF_INET: - { - struct ip_mreq mreq; - memcpy( &mreq.imr_multiaddr, - &((struct sockaddr_in *)g->addr)->sin_addr, - sizeof(struct in_addr) ); - memcpy( &mreq.imr_interface, - &((struct sockaddr_in *)s->addr)->sin_addr, - sizeof(struct in_addr) ); - if (op == JOIN_MCAST_GROUP) - sockopt = IP_ADD_MEMBERSHIP; - else - sockopt = IP_DROP_MEMBERSHIP; - if (setsockopt( s->fd, IPPROTO_IP, sockopt, - &mreq, sizeof(mreq) ) < 0) { - LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", - inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ), - errno ); - } else if (debugLevel & DEBUG_CORE) { - Debug( "XDMCP socket multicast %s to %s succeeded\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", - inet_ntoa( ((struct sockaddr_in *)g->addr)->sin_addr ) ); - } - return; - } -#if defined(IPv6) && defined(AF_INET6) -# ifndef IPV6_JOIN_GROUP -# define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP -# endif -# ifndef IPV6_LEAVE_GROUP -# define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP -# endif - case AF_INET6: - { - struct ipv6_mreq mreq6; - memcpy( &mreq6.ipv6mr_multiaddr, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - sizeof(struct in6_addr) ); - mreq6.ipv6mr_interface = 0; /* TODO: fix this */ - if (op == JOIN_MCAST_GROUP) - sockopt = IPV6_JOIN_GROUP; - else - sockopt = IPV6_LEAVE_GROUP; - if (setsockopt( s->fd, IPPROTO_IPV6, sockopt, - &mreq6, sizeof(mreq6) ) < 0) - { - int saveerr = errno; - char addrbuf[INET6_ADDRSTRLEN]; - - inet_ntop( s->addr->sa_family, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - addrbuf, sizeof(addrbuf) ); - - LogError( "XDMCP socket multicast %s to %s failed, errno %d\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf, - saveerr ); - } else if (debugLevel & DEBUG_CORE) { - char addrbuf[INET6_ADDRSTRLEN]; - - inet_ntop( s->addr->sa_family, - &((struct sockaddr_in6 *)g->addr)->sin6_addr, - addrbuf, sizeof(addrbuf) ); - - Debug( "XDMCP socket multicast %s to %s succeeded\n", - (op == JOIN_MCAST_GROUP) ? "join" : "drop", addrbuf ); - } - return; - } -#endif - } -} - -static void -UpdateMcastGroup( ARRAY8Ptr addr, void **closure ) -{ - struct socklist *s = (struct socklist *)*closure; - struct socklist *g; - - if (!s) - return; - - /* Already in the group, mark & continue */ - if ((g = FindInList( s->mcastgroups, addr ))) { - g->ref = 1; - return; - } - - /* Need to join the group */ - if (!(g = CreateSocklistEntry( addr ))) - return; - - ChangeMcastMembership( s, g, JOIN_MCAST_GROUP ); - free( g ); -} - -/* Open or close listening sockets to match the current settings read in - from the access database. */ -void -UpdateListenSockets( void ) -{ - struct socklist *s, *g, **ls, **lg; - void *tmpPtr = NULL; - - /* Clear Ref bits - any not marked by UpdateCallback will be closed */ - for (s = listensocks; s; s = s->next) { - s->ref = 0; - for (g = s->mcastgroups; g; g = g->next) - g->ref = 0; - } - ForEachListenAddr( UpdateListener, UpdateMcastGroup, &tmpPtr ); - c_request_port = request_port; - for (ls = &listensocks; (s = *ls); ) - if (!s->ref) { - DestroyListeningSocket( s ); - *ls = s->next; - free( s ); - } else { - ls = &s->next; - for (lg = &s->mcastgroups; (g = *lg); ) - if (!g->ref) { - ChangeMcastMembership( s, g, LEAVE_MCAST_GROUP ); - *lg = g->next; - free( g ); - } else - lg = &g->next; - } -} - -int -AnyListenSockets( void ) -{ - return listensocks != NULL; -} - -int -ProcessListenSockets( FD_TYPE *reads ) -{ - struct socklist *s; - int ret = 0; - - for (s = listensocks; s; s = s->next) - if (FD_ISSET( s->fd, reads )) { - ProcessRequestSocket( s->fd ); - ret = 1; - } - return ret; -} - -#endif /* !STREAMSCONN && XDMCP */ |