From aa1525793637b1323241781addf77b10e199e6e9 Mon Sep 17 00:00:00 2001 From: Alexander Barton Date: Sun, 23 Feb 2003 12:02:26 +0000 Subject: [PATCH 1/1] - Added new source module "rendezvous". --- src/ngircd/Makefile.am | 10 +- src/ngircd/rendezvous.c | 229 ++++++++++++++++++++++++++++++++++++++++ src/ngircd/rendezvous.h | 39 +++++++ 3 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 src/ngircd/rendezvous.c create mode 100644 src/ngircd/rendezvous.h diff --git a/src/ngircd/Makefile.am b/src/ngircd/Makefile.am index 3336d53a..b36b99ad 100644 --- a/src/ngircd/Makefile.am +++ b/src/ngircd/Makefile.am @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) +# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -8,7 +8,7 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: Makefile.am,v 1.36 2003/01/13 12:20:16 alex Exp $ +# $Id: Makefile.am,v 1.37 2003/02/23 12:02:26 alex Exp $ # AUTOMAKE_OPTIONS = ../portab/ansi2knr @@ -21,7 +21,8 @@ sbin_PROGRAMS = ngircd ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c conn-zip.c conn-func.c \ hash.c irc.c irc-channel.c irc-info.c irc-login.c irc-mode.c irc-op.c \ - irc-oper.c irc-server.c irc-write.c lists.c log.c match.c parse.c resolve.c + irc-oper.c irc-server.c irc-write.c lists.c log.c match.c parse.c \ + rendezvous.c resolve.c ngircd_LDFLAGS = -L../portab -L../tool @@ -29,7 +30,8 @@ ngircd_LDADD = -lngportab -lngtool noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h conn-zip.h conn-func.h \ hash.h irc.h irc-channel.h irc-info.h irc-login.h irc-mode.h irc-op.h \ - irc-oper.h irc-server.h irc-write.h lists.h log.h match.h parse.h resolve.h \ + irc-oper.h irc-server.h irc-write.h lists.h log.h match.h parse.h \ + rendezvous.h resolve.h \ messages.h defines.h clean-local: diff --git a/src/ngircd/rendezvous.c b/src/ngircd/rendezvous.c new file mode 100644 index 00000000..484ca09e --- /dev/null +++ b/src/ngircd/rendezvous.c @@ -0,0 +1,229 @@ +/* + * ngIRCd -- The Next Generation IRC Daemon + * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. + * + * Rendezvous service registration (using Mach Ports, e.g. Mac OS X) + */ + + +#include "portab.h" + +#ifdef RENDEZVOUS + + +static char UNUSED id[] = "$Id: rendezvous.c,v 1.1 2003/02/23 12:02:26 alex Exp $"; + +#include "imp.h" +#include + +#include +#include + +#ifdef HAVE_MACH_PORT_H +#include "mach/port.h" +#include "mach/message.h" +#endif + +#ifdef HAVE_DNSSERVICEDISCOVERY_DNSSERVICEDISCOVERY_H +#include +#endif + +#include "defines.h" +#include "log.h" + +#include "exp.h" +#include "rendezvous.h" + + +typedef struct _service +{ + dns_service_discovery_ref Discovery_Ref; + mach_port_t Mach_Port; + CHAR Desc[CLIENT_ID_LEN]; +} SERVICE; + + +LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, VOID *Context ); +LOCAL VOID Unregister( INT Idx ); + + +#define MAX_RENDEZVOUS 1000 +#define MAX_MACH_MSG_SIZE 512 + + +LOCAL SERVICE My_Rendezvous[MAX_RENDEZVOUS]; + + +GLOBAL VOID Rendezvous_Init( VOID ) +{ + /* Initialize structures */ + + INT i; + + for( i = 0; i < MAX_RENDEZVOUS; i++ ) + { + My_Rendezvous[i].Discovery_Ref = 0; + My_Rendezvous[i].Mach_Port = 0; + } +} /* Rendezvous_Init */ + + +GLOBAL VOID Rendezvous_Exit( VOID ) +{ + /* Clean up & exit module */ + + INT i; + + for( i = 0; i < MAX_RENDEZVOUS; i++ ) + { + if( My_Rendezvous[i].Discovery_Ref ) Unregister( i ); + } +} /* Rendezvous_Exit */ + + +GLOBAL BOOLEAN Rendezvous_Register( CHAR *Name, CHAR *Type, UINT Port ) +{ + /* Register new service */ + + INT i; + + /* Search free port structure */ + for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Discovery_Ref ) break; + if( i >= MAX_RENDEZVOUS ) + { + Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: limit (%d) reached!", Name, MAX_RENDEZVOUS ); + return FALSE; + } + strlcpy( My_Rendezvous[i].Desc, Name, sizeof( My_Rendezvous[i].Desc )); + + /* Register new service */ + My_Rendezvous[i].Discovery_Ref = DNSServiceRegistrationCreate( Name, Type, "", htonl( Port ), "", Registration_Reply_Handler, My_Rendezvous[i].Desc ); + if( ! My_Rendezvous[i].Discovery_Ref ) + { + Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: can't register service!", My_Rendezvous[i].Desc ); + return FALSE; + } + + /* Get and save the corresponding Mach Port */ + My_Rendezvous[i].Mach_Port = DNSServiceDiscoveryMachPort( My_Rendezvous[i].Discovery_Ref ); + if( ! My_Rendezvous[i].Mach_Port ) + { + Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: got no Mach Port!", My_Rendezvous[i].Desc ); + /* Here we actually leek a descriptor :-( */ + My_Rendezvous[i].Discovery_Ref = 0; + return FALSE; + } + + Log( LOG_DEBUG, "Rendezvous: Registering \"%s\" ...", My_Rendezvous[i].Desc ); + return TRUE; +} /* Rendezvous_Register */ + + +GLOBAL BOOLEAN Rendezvous_Unregister( CHAR *Name ) +{ + /* Unregister service from rendezvous */ + + INT i; + BOOLEAN ok; + + ok = FALSE; + for( i = 0; i < MAX_RENDEZVOUS; i++ ) + { + if( strcmp( Name, My_Rendezvous[i].Desc ) == 0 ) + { + Unregister( i ); + ok = TRUE; + } + } + + return ok; +} /* Rendezvous_Unregister */ + + +GLOBAL VOID Rendezvous_UnregisterListeners( VOID ) +{ + /* Unregister all our listening sockets from Rendezvous */ + + INT i; + + for( i = 0; i < MAX_RENDEZVOUS; i++ ) + { + if( strchr( My_Rendezvous[i].Desc, '.' )) Unregister( i ); + } +} /* Rendezvous_UnregisterListeners */ + + +GLOBAL VOID Rendezvous_Handler( VOID ) +{ + /* Handle all Rendezvous stuff; this function must be called + * periodically from the run loop of the main program */ + + INT i; + CHAR buffer[MAX_MACH_MSG_SIZE]; + mach_msg_return_t result; + mach_msg_header_t *msg; + + for( i = 0; i < MAX_RENDEZVOUS; i++ ) + { + if( ! My_Rendezvous[i].Discovery_Ref ) continue; + + /* Read message from Mach Port */ + msg = (mach_msg_header_t *)buffer; + result = mach_msg( msg, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, MAX_MACH_MSG_SIZE, My_Rendezvous[i].Mach_Port, 1, 0 ); + + /* Handle message */ + if( result == MACH_MSG_SUCCESS ) DNSServiceDiscovery_handleReply( msg ); +#ifdef DEBUG + else if( result != MACH_RCV_TIMED_OUT ) Log( LOG_DEBUG, "mach_msg(): %ld", (LONG)result ); +#endif + } +} /* Rendezvous_Handler */ + + +LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, VOID *Context ) +{ + CHAR txt[50]; + + if( ErrCode == kDNSServiceDiscoveryNoError ) + { + /* Success! */ + Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", Context ? Context : "NULL" ); + return; + } + + switch( ErrCode ) + { + case kDNSServiceDiscoveryAlreadyRegistered: + strcpy( txt, "name already registered!" ); + break; + case kDNSServiceDiscoveryNameConflict: + strcpy( txt, "name conflict!" ); + break; + default: + sprintf( txt, "error code %ld!", (LONG)ErrCode ); + } + + Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", Context ? Context : "NULL", txt ); +} /* Registration_Reply_Handler */ + + +LOCAL VOID Unregister( INT Idx ) +{ + /* Unregister service */ + + DNSServiceDiscoveryDeallocate( My_Rendezvous[Idx].Discovery_Ref ); + Log( LOG_INFO, "Unregistered \"%s\" from Rendezvous.", My_Rendezvous[Idx].Desc ); + My_Rendezvous[Idx].Discovery_Ref = 0; +} /* Unregister */ + + +#endif /* RENDEZVOUS */ + + +/* -eof- */ diff --git a/src/ngircd/rendezvous.h b/src/ngircd/rendezvous.h new file mode 100644 index 00000000..fa1d30c2 --- /dev/null +++ b/src/ngircd/rendezvous.h @@ -0,0 +1,39 @@ +/* + * ngIRCd -- The Next Generation IRC Daemon + * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. + * + * $Id: rendezvous.h,v 1.1 2003/02/23 12:02:26 alex Exp $ + * + * "Rendezvous" functions (Header) + */ + + +#ifdef RENDEZVOUS + +#ifndef __rdezvous_h__ +#define __rdezvous_h__ + + +GLOBAL VOID Rendezvous_Init( VOID ); +GLOBAL VOID Rendezvous_Exit( VOID ); + +GLOBAL BOOLEAN Rendezvous_Register( CHAR *Name, CHAR *Type, UINT Port ); + +GLOBAL BOOLEAN Rendezvous_Unregister( CHAR *Name ); +GLOBAL VOID Rendezvous_UnregisterListeners( VOID ); + +GLOBAL VOID Rendezvous_Handler( VOID ); + + +#endif /* __rdezvous_h__ */ + +#endif /* RENDEZVOUS */ + + +/* -eof- */ -- 2.39.2