📄 rsvp_main.c
字号:
/* * @(#) $Id: rsvp_main.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_main.c ******************************* * * * RSVP daemon: main routine, initialization, and I/O control * * routines. Generally, system-dependent code. * * * *********************************************************************//**************************************************************************** RSVPD -- ReSerVation Protocol Daemon USC Information Sciences Institute Marina del Rey, California Original Version: Shai Herzog, Nov. 1993. Current Version: Steven Berson & Bob Braden, May 1996 Copyright (c) 1996 by the University of Southern California All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation in source and binary forms for any purpose and without fee is hereby granted, provided that both the above copyright notice and this permission notice appear in all copies, and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed in part by the University of Southern California, Information Sciences Institute. The name of the University may not be used to endorse or promote products derived from this software without specific prior written permission. THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about the suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Other copyrights might apply to parts of this software and are so noted when applicable.********************************************************************/#define __MAIN__#include "rsvp_daemon.h"#include "rsvp_api.h"#include <sys/stat.h>#include <fcntl.h>#include <sys/resource.h>#ifdef SOLARIS#include <sys/time.h>#include <sys/sockio.h> /* for SIOCGIFCONF (for SOLARIS) */#include <sys/termios.h> /* for TIOCNOTTY (for SOLARIS) */#endif /* SOLARIS */static struct rlimit limits;#define RSVP_LOCK_PORT 5434 /* port number for rsvpd lock */static int lockfd = SYS_ERROR; /* fd for holding rsvpd lock */static char rsvp_log_suffix[16];/* Data structure for main select() loop */static fd_set fds; /* bit vector for select *//* Sockets and addresses */static int api_socket; /* Unix listen sock for API *//* static int api_udp_socket; */ /* UDP listen sock for API */int probe_socket; /* Sock to rcv status probe */int mstat_ttl = 1; /* IP TTL for multicasting status: * Note small default! */int refresh_default = REFRESH_DEFAULT; /* Default R */int api_refresh_t = API_REFRESH_T; /* Default API refresh T */char recv_buff[MAX_PKT + sizeof(struct ip)];extern struct in_addr encap_group; /* Gu */extern u_int16_t encap_port; /* Pu */extern u_int16_t encap_portp; /* Pu' */extern net_addr *encap_router;extern net_addr encap_mc_addr;#ifdef USE_IPV6extern struct in6_addr encap_group6; /* Gu */extern net_addr encap_mc_addr6;#endif /* USE_IPV6 *//*extern int use_udp;*//* * Test facility variables */#define MAX_DEBUG_FILTER 10net_addr debug_filters[MAX_DEBUG_FILTER];int debug_filter_num = 0;int debug_filter = 0;int Test_mode = 0;net_addr *tsttun_vec;int *tst_sock2if;/* * Global RSRR variables. */#ifndef HOST_ONLYextern struct sockaddr_un cli_addr_v4; /* Client address */#ifdef USE_IPV6extern struct sockaddr_un cli_addr_v6; /* Client address */#endif /* USE_IPV6 */#endif /* ! HOST_ONLY *//* External RSRR definitions. */extern int rsrr_socket; /* interface to reservation protocol */#ifdef USE_IPV6extern int rsrr_socket_v6;#endif /* USE_IPV6 */extern int rsrr_initial_reply;extern int rsrr_dispatch();#ifndef HOST_ONLYextern int rsrr_interface_query(); /* RSRR Interface Query */#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux)extern int rskt;#endif /* PF_ROUTE */#endif /* ! HOST_ONLY *//* External declarations */int process_api_req(int, rsvp_req *, int);int api_status(rsvp_req *);extern char vers_comp_date[]; /* version & compilation date/time */void hexf();void del_from_timer();u_long next_event_time();void init_route();void init_probe_socket();void send_rsvp_state(char *, int, struct sockaddr_in *);void api_free_packet(struct packet *);int next_word(char **, char *), pfxcmp(char *, char *);void KernTC_if_init(int);void ntoh_api_request(rsvp_req *, int);#ifdef RTAPvoid rtap_init(), rtap_loop(fd_set *), rtap_command();void rtap_dispatch();int rtap_insock, rtap_fd;#endif/* forward declarations */void rsvp_api_close(int);static int init_rsvp(void);int save_pid(void);static void sigpipe(int);static void final();int api_input(int);int status_probe(int ifd);int start_UDP_encap(int);int api_cmd(int, rapi_cmd_t *);static void sigint_handler(int);int find_sid(int fd, int pid, int client_sid); int find_free_sid(int fd, int pid, int client_sid);void print_ifs();void read_config_file(char *);void cfig_action(int, char *, char *);void cfig_do(char **, char *);KEY_ASSOC *load_key(char *, char *);void ntoh_rapi_cmd(rapi_cmd_t *);voidUsage(char *namep) { fprintf(stderr,"Usage: %s [-D] [-d debug_bits] [-l debug_level] [-t mstat_ttl] \n", namep);}/* * Define table giving syntax of configuration file */typedef struct { char *cfig_keywd; char cfig_flags;#define CFF_CMDOP 0x01#define CFF_HASPARM 0x02#define CFF_HASPARM2 0x04 char cfig_actno;} Cfig_element;enum { CfAct_iface, CfAct_police, CfAct_udp, CfAct_udpttl, CfAct_intgr, CfAct_disable, CfAct_sndttl, CfAct_refresh, CfAct_sendkey,CfAct_recvkey};/* interface <name> [police] [udp] [udpttl <#>] [integrity] * [disable] [sendttl <#>] [refresh <#>] * * XXX Should add: [type <type name, eg atm>] => call appropriate * XXX LL interface vector initialization routine: * XXX <type>_if_init(if#) * XXX Default is: KernTC_if_init(if#) */Cfig_element Cfig_Table[] = { {"interface", CFF_CMDOP+CFF_HASPARM, CfAct_iface}, {"police", 0, CfAct_police}, {"udpencap", 0, CfAct_udp}, {"udpttl", CFF_HASPARM, CfAct_udpttl}, {"integrity", 0, CfAct_intgr}, {"disable", 0, CfAct_disable}, {"refresh", CFF_HASPARM, CfAct_refresh}, {"sendkey", CFF_HASPARM2, CfAct_sendkey}, {"sendttl", CFF_HASPARM, CfAct_sndttl}, {"recvkey", CFF_CMDOP+CFF_HASPARM2, CfAct_recvkey}, {NULL, 0, 0} /* Fence: ends table */};int Cfig_if; /* Global interface number for config file */Cfig_element *cfig_search(char *);/* * * The main() routine for rsvpd, the RSVP daemon. * */intmain(int argc, char *argv[]) { int fd_wid, rc, fd_val, newsock, zero = 0; fd_set tmp_fds, rset; extern char *optarg; extern int optind; u_int c; struct timeval t_intvl; struct timeval t_old, t_new; int delta; int Daemonize = 1; int Rflag = 0; char *R_arg; /* * Set defaults */ m_debug = l_debug = -1; Max_rsvp_msg = MAX_PKT; /* * Process options */ while ((c = getopt(argc, argv, "Dd:l:t:R:r:")) != -1) { switch (c) { case 'D': /* -D => debug mode, i.e. do not daemonize */ Daemonize = 0; break; case 'd': m_debug = atoi(optarg); break; case 'l': l_debug = atoi(optarg); break; case 't': /* -t: specify TTL for multicasting status info */ mstat_ttl = atoi(optarg); break; case 'R': /* -R: specify name/address of RSVP-capable * router to receive encapsulated Path messages. */ Rflag = 1; R_arg = optarg; break;#ifdef DEBUG case 's': /* max message size (for debugging) */ Max_rsvp_msg = atoi(optarg); break; case 'x': /* -x: test mode. */ Test_mode = 1; break; case 'r': /*default refresh timeout period in ms */ refresh_default = /* api_refresh_t = */ atoi(optarg); break;#endif case '?': default: Usage(argv[0]); exit(1); } } if (optind != argc) { Usage(argv[0]); exit(1); } /* * If there is already an RSVP daemon running (as shown by existence * of pid file), exit immediately. */ if ((rc = test_alive())) { fprintf(stderr, "RSVP daemon is already running, with PID=%d\n", rc); exit(-1); } /* Set debugging defaults if none given */ if (m_debug < 0) m_debug = (Daemonize)? BK_DFLT_DEBUG_MASK : FG_DFLT_DEBUG_MASK; if (l_debug < 0) l_debug = (Daemonize)? BK_DFLT_LOGGING_LEVEL: FG_DFLT_LOGGING_LEVEL; (void) getrlimit(RLIMIT_NOFILE, &limits); /* * Daemonize, if requested. */ if (Daemonize) {#if BSD >= 199306 daemon(1, 0);#else#ifdef sgi _daemonize(0, -1, -1, -1);#else int i; if (fork()) exit(0); for (i = 0; i < limits.rlim_cur; i++) if (i != lockfd) (void) close(i); (void) open("/", O_RDONLY); (void) dup2(0, 1); (void) dup2(0, 2); i = open("/dev/tty", O_RDWR); if (i >= 0) { (void) ioctl(i, (int) TIOCNOTTY, (char *)0); (void) close(i); }#endif /* sgi */#endif /* BSD */ } /* * Initialize RSVP */ signal(SIGPIPE, sigpipe); signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler);#ifdef SunOS on_exit(final,0);#else /* SunOS */ atexit(final);#endif /* SunOS */ reset_log(1); /* Initialize log and print header */ if (Rflag) { static net_addr addr; if (net_addr_ascii(&addr,R_arg)) encap_router = &addr; else log(LOG_ERR, 0, "Unknown router %s", R_arg); } if (save_pid() == -1) { log(LOG_ERR, 0, "save_pid() failed!\n"); exit(-1); } if (init_rsvp() == -1) { log(LOG_ERR, 0, "RSVP initialization failed.\n", 0); exit(-1); } if (!NoV4Mroute) if (geteuid() != 0) { log(LOG_ERR, 0, "RSVP must be run with root privilege on a router.\n", 0); exit(-1); } FD_SET(api_socket, &fds); /* FD_SET(api_udp_socket, &fds); */ FD_SET(probe_socket, &fds);#ifndef HOST_ONLY if (!NoV4Mroute) { FD_SET(rsrr_socket, &fds); }#ifdef USE_IPV6 if (!NoV6Mroute) { FD_SET(rsrr_socket_v6, &fds); }#endif /* USE_IPV6 */#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux) if (!NoUnicast) { FD_SET(rskt, &fds); }#endif /* PF_ROUTE */#endif /* ! HOST_ONLY */#ifdef RTAP rtap_fd = rtap_insock = -1; if (!Daemonize) rtap_init();#endif /* XXX Configure max # simultaneous API sessions (=> fd_wid) ?? */ /* * Main control loop */#ifdef SOLARIS fd_wid = sysconf(_SC_OPEN_MAX);#else fd_wid = getdtablesize();#endif for (;;) { memcpy((char *) &tmp_fds, (char *) &fds, sizeof(fds));#ifdef RTAP if (!Daemonize) rtap_loop(&tmp_fds);#endif gettimeofday(&t_old, NULL); delta = next_event_time(); if (delta == -1) rc = select(fd_wid, &tmp_fds, (fd_set *) NULL, (fd_set *) NULL, NULL); else { delta -= time_now; t_intvl.tv_sec = delta/1000; t_intvl.tv_usec = 1000*(delta%1000); rc = select(fd_wid, &tmp_fds, (fd_set *) NULL, (fd_set *) NULL, &t_intvl); } if (rc == -1) { log(LOG_ERR, errno, "Bad return from select()\n"); assert(errno == EINTR); continue; } gettimeofday(&t_new, NULL); delta = (t_new.tv_sec - t_old.tv_sec) * 1000 + (t_new.tv_usec - t_old.tv_usec)/1000; time_now += delta; timer_wakeup(0); assert(rc >= 0); net_poll_list(&rset); for (fd_val = 0; rc--; fd_val++) { /* Locate the next fd bit that is set, then dispatch * on it. */ while (!FD_ISSET(fd_val, &tmp_fds)) fd_val++;#ifndef HOST_ONLY if (fd_val == rsrr_socket && !NoV4Mroute) { rsrr_dispatch(); } else#ifdef USE_IPV6 if (fd_val == rsrr_socket_v6 && !NoV6Mroute) { rsrr_dispatch(); } else#endif /* USE_IPV6 */#endif /* ! HOST_ONLY */ if (fd_val == api_socket) { /* * API connection request from client; get a * new socket for this connection and add it * to the select list. */ newsock = accept(api_socket, (struct sockaddr *) NULL, &zero); if (newsock == -1) { log(LOG_ERR, errno, "accept error\n"); continue; } FD_SET(newsock, &fds); } else if (fd_val == probe_socket) { /* Status probe packet arrived. */ status_probe(fd_val); }#ifdef RTAP else if (fd_val == rtap_insock) rtap_command(); else if (fd_val == rtap_fd) rtap_dispatch(); #endif /* RTAP */ else if (FD_ISSET(fd_val,&rset)) rsvp_input(fd_val); /* else if (fd_val == api_udp_socket) { use_udp = 1; api_input(fd_val); } */#if defined(PF_ROUTE) && !defined(sgi_53) && !defined(linux) else if (fd_val != rskt) { /* * RSVP API input from UNIX socket */ /* use_udp = 0; */ api_input(fd_val); } else rsrr_dispatch();#else else { /* * RSVP API input from UNIX socket */ /* use_udp = 0; */ api_input(fd_val); }#endif /* PF_ROUTE */ } }}staticvoidfinal(){ net_final();#ifndef HOST_ONLY /* Clean up the RSRR socket. */ unlink(cli_addr_v4.sun_path);#ifdef USE_IPV6 unlink(cli_addr_v6.sun_path);#endif /* USE_IPV6 */#endif /* ! HOST_ONLY */ unlink(RSVP_PID_FILE); unlink(SNAME);}static voidsigpipe(int sig) { log(LOG_DEBUG, 0, "Got a SIGPIPE\n"); signal(SIGPIPE, sigpipe);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -