dbus_mgr.c
来自「非常好的dns解析软件」· C语言 代码 · 共 2,442 行 · 第 1/5 页
C
2,442 行
/* dbus_mgr.c * * named module to provide dynamic forwarding zones in * response to D-BUS dhcp events or commands. * * Copyright(C) Jason Vas Dias, Red Hat Inc., 2005 * * 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 at * http://www.fsf.org/licensing/licenses/gpl.txt * and included in this software distribution as the "LICENSE" file. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */#include <config.h>#include <isc/types.h>#include <isc/net.h>#include <isc/mem.h>#include <isc/magic.h>#include <isc/list.h>#include <isc/task.h>#include <isc/event.h>#include <isc/socket.h>#include <isc/timer.h>#include <isc/netaddr.h>#include <isc/sockaddr.h>#include <isc/buffer.h>#include <isc/log.h>#include <dns/name.h>#include <dns/acl.h>#include <dns/fixedname.h>#include <dns/view.h>#include <dns/forward.h>#include <named/types.h>#include <named/config.h>#include <named/server.h>#include <named/globals.h>#include <named/log.h>#include <named/dbus_service.h>#include <named/dbus_mgr.h>#include <string.h>#include <search.h>typedef void (*__free_fn_t) (void *__nodep);extern void tdestroy (void *__root, __free_fn_t __freefct);extern void free(void*);#ifdef ISC_USE_INTERNAL_MALLOC# if ISC_USE_INTERNAL_MALLOC# error dbus_mgr cannot be used if ISC_USE_INTERNAL_MALLOC==1# endif#endif#define DBUSMGR_DESTINATION "com.redhat.named"#define DBUSMGR_OBJECT_PATH "/com/redhat/named"#define DBUSMGR_INTERFACE "com.redhat.named"#define DBUSMGR_MAGIC ISC_MAGIC('D', 'B', 'U', 'S')struct ns_dbus_mgr{ unsigned int magic; isc_mem_t * mctx; /* Memory context. */ isc_taskmgr_t * taskmgr; /* Task manager. */ isc_socketmgr_t * socketmgr; /* Socket manager. */ isc_timermgr_t * timermgr; /* Timer manager. */ isc_task_t * task; /* task */ isc_timer_t * timer; /* dbus_init retry */ void * sockets; /* dbus fd tree */ void * dhc_if; /* dhcp interface tree */ void * ifwdt; /* initial forwarder tree */ char * dhcdbd_name; /* dhcdbd destination */ DBUS_SVC dbus; /* dbus handle */};typedefstruct dbus_mgr_sock_s{ int fd; struct ns_dbus_mgr *mgr; isc_socket_t *sock; isc_socketevent_t *ser; isc_socketevent_t *sew; isc_socketevent_t *sel;} DBusMgrSocket;typedefenum dhc_state_e{ DHC_NBI, /* no broadcast interfaces found */ DHC_PREINIT, /* configuration started */ DHC_BOUND, /* lease obtained */ DHC_RENEW, /* lease renewed */ DHC_REBOOT, /* have valid lease, but now obtained a different one */ DHC_REBIND, /* new, different lease */ DHC_STOP, /* remove old lease */ DHC_MEDIUM, /* media selection begun */ DHC_TIMEOUT, /* timed out contacting DHCP server */ DHC_FAIL, /* all attempts to contact server timed out, sleeping */ DHC_EXPIRE, /* lease has expired, renewing */ DHC_RELEASE, /* releasing lease */ DHC_START, /* sent when dhclient started OK */ DHC_ABEND, /* dhclient exited abnormally */ DHC_END, /* dhclient exited normally */ DHC_END_OPTIONS, /* last option in subscription sent */ DHC_INVALID=255 } DHC_State;typedef ISC_LIST(dns_name_t) DNSNameList;typedef ISC_LIST(isc_sockaddr_t) SockAddrList;typedef struct dbm_fwdr_s{ dns_fwdpolicy_t fwdpolicy; dns_name_t dn; SockAddrList sa; ISC_LINK( struct dbm_fwdr_s ) link;} DBusMgrInitialFwdr;typedefstruct dhc_if_s{ char *if_name; DHC_State dhc_state; DHC_State previous_state; struct in_addr ip; struct in_addr subnet_mask; DNSNameList dn; SockAddrList dns;} DHC_IF;static void dbus_mgr_watch_handler( int fd, dbus_svc_WatchFlags flags, void *mgrp );staticdbus_svc_HandlerResult dbus_mgr_message_handler( DBusMsgHandlerArgs);staticvoid dbus_mgr_close_socket( const void *p, const VISIT which, const int level);staticvoid dbus_mgr_destroy_socket( void *p );staticvoid dbus_mgr_free_dhc( void *p );static voiddbus_mgr_watches_selected(isc_task_t *t, isc_event_t *ev);static isc_result_tdbus_mgr_init_dbus(ns_dbus_mgr_t *);static isc_result_tdbus_mgr_record_initial_fwdtable(ns_dbus_mgr_t *);static voiddbus_mgr_free_initial_fwdtable(ns_dbus_mgr_t *);static uint8_t dbus_mgr_subscribe_to_dhcdbd( ns_dbus_mgr_t * );static void dbus_mgr_dbus_shutdown_handler ( ns_dbus_mgr_t * );staticint dbus_mgr_log_err( const char *fmt, ...){ va_list va; va_start(va, fmt); isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_DBUS, NS_LOGMODULE_DBUS, ISC_LOG_NOTICE, fmt, va ); va_end(va); return 0;}staticint dbus_mgr_log_dbg( const char *fmt, ...){ va_list va; va_start(va, fmt); isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_DBUS, NS_LOGMODULE_DBUS, ISC_LOG_DEBUG(80), fmt, va ); va_end(va); return 0;}staticint dbus_mgr_log_info( const char *fmt, ...){ va_list va; va_start(va, fmt); isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_DBUS, NS_LOGMODULE_DBUS, ISC_LOG_DEBUG(1), fmt, va ); va_end(va); return 0;}isc_result_t dbus_mgr_create( isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, ns_dbus_mgr_t **dbus_mgr){ isc_result_t result; ns_dbus_mgr_t *mgr; *dbus_mgr = 0L; mgr = isc_mem_get(mctx, sizeof(*mgr)); if (mgr == NULL) return (ISC_R_NOMEMORY); mgr->magic = DBUSMGR_MAGIC; mgr->mctx = mctx; mgr->taskmgr = taskmgr; mgr->socketmgr = socketmgr; mgr->timermgr = timermgr; mgr->task = 0L; mgr->sockets = 0L; mgr->timer = 0L; mgr->dhc_if = 0L; mgr->ifwdt = 0L; mgr->dhcdbd_name = 0L; if( (result = isc_task_create( taskmgr, 100, &(mgr->task))) != ISC_R_SUCCESS ) goto cleanup_mgr; isc_task_setname( mgr->task, "dbusmgr", mgr ); mgr->dbus = 0L; if( (result = dbus_mgr_record_initial_fwdtable( mgr )) != ISC_R_SUCCESS ) goto cleanup_mgr; if( (result = dbus_mgr_init_dbus( mgr )) != ISC_R_SUCCESS ) goto cleanup_mgr; *dbus_mgr = mgr; return ISC_R_SUCCESS; cleanup_mgr: if( mgr->task != 0L ) isc_task_detach(&(mgr->task)); isc_mem_put(mctx, mgr, sizeof(*mgr)); return (result);}static isc_result_tdbus_mgr_init_dbus(ns_dbus_mgr_t * mgr){ char destination[]=DBUSMGR_DESTINATION; if( mgr->sockets != 0L ) { isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L); twalk(mgr->sockets, dbus_mgr_close_socket); tdestroy(mgr->sockets, dbus_mgr_destroy_socket); mgr->sockets = 0L; } if( mgr->dbus != 0L ) { dbus_svc_shutdown(mgr->dbus); mgr->dbus = 0L; } mgr->dbus = dbus_svc_init ( DBUS_PRIVATE_SYSTEM, destination, dbus_mgr_watch_handler, 0L, 0L, mgr ); if( mgr->dbus == 0L ) { if( mgr->timer == 0L) { isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L); if( mgr->sockets != 0L ) { twalk(mgr->sockets, dbus_mgr_close_socket); tdestroy(mgr->sockets, dbus_mgr_destroy_socket); mgr->sockets = 0L; } dbus_mgr_dbus_shutdown_handler ( mgr ); return ISC_R_SUCCESS; } goto cleanup; } if( !dbus_svc_add_filter ( mgr->dbus, dbus_mgr_message_handler, mgr, 4, "type=signal,path=/org/freedesktop/DBus,member=NameOwnerChanged", "type=signal,path=/org/freedesktop/DBus/Local,member=Disconnected", "type=signal,interface=com.redhat.dhcp.subscribe.binary", "type=method_call,destination=com.redhat.named,path=/com/redhat/named" ) ) { dbus_mgr_log_err( "dbus_svc_add_filter failed" ); goto cleanup; } if( mgr->timer != 0L ) { isc_timer_reset(mgr->timer, isc_timertype_inactive, NULL, NULL, ISC_TRUE ); } if( !dbus_mgr_subscribe_to_dhcdbd( mgr ) ) dbus_mgr_log_err("D-BUS dhcdbd subscription disabled."); dbus_mgr_log_err("D-BUS service enabled."); return ISC_R_SUCCESS; cleanup: isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L); twalk(mgr->sockets, dbus_mgr_close_socket); tdestroy(mgr->sockets, dbus_mgr_destroy_socket); mgr->sockets = 0L; if( mgr->dbus ) { dbus_svc_shutdown(mgr->dbus); mgr->dbus = 0L; } return ISC_R_FAILURE;}static uint8_t dbus_mgr_subscribe_to_dhcdbd( ns_dbus_mgr_t *mgr ){ DBUS_SVC dbus = mgr->dbus; char subs[1024], path[1024], dhcdbd_destination[]="com.redhat.dhcp", *ddp[1]={ &(dhcdbd_destination[0]) }, *dhcdbd_name=0L; const char *options[] = { "reason", "ip-address", "subnet-mask", "domain-name", "domain-name-servers" }; dbus_svc_MessageHandle msg; int i, n_opts = 5; if( mgr->dhcdbd_name == 0L ) { msg = dbus_svc_call ( dbus, "org.freedesktop.DBus", "/org/freedesktop/DBus", "GetNameOwner", "org.freedesktop.DBus", TYPE_STRING, &ddp, TYPE_INVALID ); if( msg == 0L ) return 0; if( !dbus_svc_get_args(dbus, msg, TYPE_STRING, &(dhcdbd_name), TYPE_INVALID ) ) return 0; mgr->dhcdbd_name = isc_mem_get(mgr->mctx, strlen(dhcdbd_name) + 1); if( mgr->dhcdbd_name == 0L ) return 0; strcpy(mgr->dhcdbd_name, dhcdbd_name); } sprintf(path,"/com/redhat/dhcp/subscribe"); sprintf(subs,"com.redhat.dhcp.binary"); for(i = 0; i < n_opts; i++) { msg = dbus_svc_call ( dbus, "com.redhat.dhcp", path, "binary", subs, TYPE_STRING, &(options[i]), TYPE_INVALID ); if(msg == 0L) return 0; if ( dbus_svc_message_type( msg ) == ERROR ) return 0; } dbus_mgr_log_err("D-BUS dhcdbd subscription enabled."); return 1;}void dbus_mgr_shutdown( ns_dbus_mgr_t *mgr){ if( mgr->timer != 0L ) isc_timer_detach(&(mgr->timer)); if( mgr->dbus != 0L ) { isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L); if( mgr->sockets != 0L ) { twalk(mgr->sockets, dbus_mgr_close_socket); tdestroy(mgr->sockets, dbus_mgr_destroy_socket); mgr->sockets = 0L; } dbus_svc_shutdown(mgr->dbus); } if( mgr->dhc_if != 0L ) tdestroy(mgr->dhc_if, dbus_mgr_free_dhc); if( mgr->dhcdbd_name != 0L ) isc_mem_put(mgr->mctx, mgr->dhcdbd_name, strlen(mgr->dhcdbd_name) + 1); isc_task_detach(&(mgr->task)); dbus_mgr_free_initial_fwdtable(mgr); isc_mem_put(mgr->mctx, mgr, sizeof(ns_dbus_mgr_t));}static void dbus_mgr_restart_dbus(isc_task_t *t, isc_event_t *ev){ ns_dbus_mgr_t *mgr = (ns_dbus_mgr_t*)(ev->ev_arg) ; t=t; isc_event_free(&ev); dbus_mgr_log_dbg("attempting to connect to D-BUS"); dbus_mgr_init_dbus( mgr );}staticvoid dbus_mgr_handle_dbus_shutdown_event(isc_task_t *t, isc_event_t *ev){ ns_dbus_mgr_t *mgr = ev->ev_arg; isc_time_t tick={10,0}; isc_interval_t tock={10,0}; DBUS_SVC dbus = mgr->dbus; t = t; mgr->dbus = 0L; isc_event_free(&ev); if ( dbus != 0L ) { isc_task_purgerange(mgr->task, 0L, ISC_SOCKEVENT_READ_READY, ISC_SOCKEVENT_SELECTED, 0L); if( mgr->sockets != 0L ) { twalk(mgr->sockets, dbus_mgr_close_socket); tdestroy(mgr->sockets, dbus_mgr_destroy_socket); mgr->sockets = 0L; } dbus_svc_shutdown(dbus); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?