⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipvsadm.c

📁 实现了集群的实现 完成了资源负载平衡等问题
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *      ipvsadm - IP Virtual Server ADMinistration program *                for IPVS NetFilter Module in kernel 2.4 * *      Version: $Id: ipvsadm.c,v 1.27 2005/12/10 16:00:07 wensong Exp $ * *      Authors: Wensong Zhang <wensong@linuxvirtualserver.org> *               Peter Kese <peter.kese@ijs.si> * *      This program is based on ippfvsadm. * *      Changes: *        Wensong Zhang       :   added the editting service & destination support *        Wensong Zhang       :   added the feature to specify persistent port *        Jacob Rief          :   found the bug that masquerading dest of *                                different vport and dport cannot be deleted. *        Wensong Zhang       :   fixed it and changed some cosmetic things *        Wensong Zhang       :   added the timeout setting for persistent service *        Wensong Zhang       :   added specifying the dest weight zero *        Wensong Zhang       :   fixed the -E and -e options *        Wensong Zhang       :   added the long options *        Wensong Zhang       :   added the hostname and portname input *        Wensong Zhang       :   added the hostname and portname output *	  Lars Marowsky-Br閑  :   added persistence granularity support *        Julian Anastasov    :   fixed the (null) print for unknown services *        Wensong Zhang       :   added the port_to_anyname function *        Horms               :   added option to read commands from stdin *        Horms               :   modified usage function so it prints to *                            :   stdout if an exit value of 0 is used and *                            :   stdout otherwise. Program is then terminated *                            :   with the supplied exit value. *        Horms               :   updated manpage and usage funtion so *                            :   the reflect the options available *        Wensong Zhang       :   added option to write rules to stdout *        Horms               :   added ability to specify a fwmark *                            :   instead of a server and port for *                            :   a virtual service *        Horms               :   tightened up checking of services *                            :   in parse_service *        Horms               :   ensure that a -r is passed when needed *        Wensong Zhang       :   fixed the output of fwmark rules *        Horms               :   added kernel version verification *        Horms               :   Specifying command and option options *                                (e.g. -Ln or -At) in one short option *                                with popt problem fixed. *        Wensong Zhang       :   split the process_options and make *                                two versions of parse_options. *        Horms               :   attempting to save or restore when *                                compiled against getopt_long now results *                                in an informative error message rather *                                than the usage information *        Horms               :   added -v option *        Wensong Zhang       :   rewrite most code of parsing options and *                                processing options. *        Alexandre Cassen    :   added ipvs_syncd SyncdID support to filter *                                incoming sync messages. *        Guy Waugh & Ratz    :   added --exact option and spelling cleanup * * *      ippfvsadm - Port Fowarding & Virtual Server ADMinistration program * *      Copyright (c) 1998 Wensong Zhang *      All rights reserved. * *      Author: Wensong Zhang <wensong@iinchina.net> * *      This ippfvsadm is derived from Steven Clarke's ipportfw program. * *      portfw - Port Forwarding Table Editing v1.1 * *      Copyright (c) 1997 Steven Clarke *      All rights reserved. * *      Author: Steven Clarke <steven@monmouth.demon.co.uk> * *      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. * *      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. * *      You should have received a copy of the GNU General Public License *      along with this program; if not, write to the Free Software *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#undef __KERNEL__	/* Makefile lazyness ;) */#include <stdio.h>#include <stdlib.h>#include <getopt.h>#include <netdb.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <ctype.h>#include <stdarg.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/param.h>#include <sys/wait.h>           /* For waitpid */#include <arpa/inet.h>#include <net/if.h>#include <netinet/ip_icmp.h>#include <netinet/udp.h>#include <netinet/tcp.h>#ifdef HAVE_POPT#include "popt.h"#define IPVS_OPTION_PROCESSING	"popt"#else#define IPVS_OPTION_PROCESSING	"getopt_long"#endif#include "config_stream.h"#include "libipvs/libipvs.h"#define IPVSADM_VERSION_NO	"v" VERSION#define IPVSADM_VERSION_DATE	"2005/12/10"#define IPVSADM_VERSION		IPVSADM_VERSION_NO " " IPVSADM_VERSION_DATE#define MAX_TIMEOUT		(86400*31)	/* 31 days */#define CMD_NONE		0#define CMD_ADD			(CMD_NONE+1)#define CMD_EDIT		(CMD_NONE+2)#define CMD_DEL			(CMD_NONE+3)#define CMD_FLUSH		(CMD_NONE+4)#define CMD_LIST		(CMD_NONE+5)#define CMD_ADDDEST		(CMD_NONE+6)#define CMD_DELDEST		(CMD_NONE+7)#define CMD_EDITDEST		(CMD_NONE+8)#define CMD_TIMEOUT		(CMD_NONE+9)#define CMD_STARTDAEMON		(CMD_NONE+10)#define CMD_STOPDAEMON		(CMD_NONE+11)#define CMD_RESTORE		(CMD_NONE+12)#define CMD_SAVE		(CMD_NONE+13)#define CMD_ZERO		(CMD_NONE+14)#define CMD_MAX			CMD_ZERO#define NUMBER_OF_CMD		(CMD_MAX - CMD_NONE)static const char* cmdnames[] = {	"add-service",	"edit-service",	"delete-service",	"flush",	"list",	"add-server",	"delete-server",	"edit-server",	"set",	"start-daemon",	"stop-daemon",	"restore",	"save",	"zero",};#define OPT_NONE		0x000000#define OPT_NUMERIC		0x000001#define OPT_CONNECTION		0x000002#define OPT_SERVICE		0x000004#define OPT_SCHEDULER		0x000008#define OPT_PERSISTENT		0x000010#define OPT_NETMASK		0x000020#define OPT_SERVER		0x000040#define OPT_FORWARD		0x000080#define OPT_WEIGHT		0x000100#define OPT_UTHRESHOLD		0x000200#define OPT_LTHRESHOLD		0x000400#define OPT_MCAST		0x000800#define OPT_TIMEOUT		0x001000#define OPT_DAEMON		0x002000#define OPT_STATS		0x004000#define OPT_RATE		0x008000#define OPT_THRESHOLDS		0x010000#define OPT_PERSISTENTCONN	0x020000#define OPT_SORT		0x040000#define OPT_SYNCID		0x080000#define OPT_EXACT		0x100000#define NUMBER_OF_OPT		21static const char* optnames[] = {	"numeric",	"connection",	"service-address",	"scheduler",	"persistent",	"netmask",	"real-server",	"forwarding-method",	"weight",	"u-threshold",	"l-threshold",	"mcast-interface",	"timeout",	"daemon",	"stats",	"rate",	"thresholds",	"persistent-conn",	"sort",	"syncid",	"exact",};/* * Table of legal combinations of commands and options. * Key: *  '+'  compulsory *  'x'  illegal *  '1'  exclusive (only one '1' option can be supplied) *  ' '  optional */static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] ={	/*   -n   -c   svc  -s   -p   -M   -r   fwd  -w   -x   -y   -mc  tot  dmn  -st  -rt  thr  -pc  srt  sid  -ex *//*ADD*/     {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*EDIT*/    {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*DEL*/     {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*FLUSH*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*LIST*/    {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' '},/*ADDSRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*DELSRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*STARTD*/  {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*STOPD*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*SAVE*/    {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},/*ZERO*/    {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},};/* printing format flags */#define FMT_NONE		0x0000#define FMT_NUMERIC		0x0001#define FMT_RULE		0x0002#define FMT_STATS		0x0004#define FMT_RATE		0x0008#define FMT_THRESHOLDS		0x0010#define FMT_PERSISTENTCONN	0x0020#define FMT_SORT		0x0040#define FMT_EXACT		0x0080#define SERVICE_NONE		0x0000#define SERVICE_ADDR		0x0001#define SERVICE_PORT		0x0002/* default scheduler */#define DEF_SCHED		"wlc"/* default multicast interface name */#define DEF_MCAST_IFN		"eth0"#define CONN_PROC_FILE		"/proc/net/ip_vs_conn"struct ipvs_command_entry {	int			cmd;	ipvs_service_t		svc;	ipvs_dest_t		dest;	ipvs_timeout_t		timeout;	ipvs_daemon_t		daemon;};/* various parsing helpers & parsing functions */static int str_is_digit(const char *str);static int string_to_number(const char *s, int min, int max);static int host_to_addr(const char *name, struct in_addr *addr);static char * addr_to_host(struct in_addr *addr);static char * addr_to_anyname(struct in_addr *addr);static int service_to_port(const char *name, unsigned short proto);static char * port_to_service(unsigned short port, unsigned short proto);static char * port_to_anyname(unsigned short port, unsigned short proto);static char * addrport_to_anyname(struct in_addr *addr, unsigned short port,				  unsigned short proto, unsigned int format);static int parse_service(char *buf, u_int16_t proto,			 u_int32_t *addr, u_int16_t *port);static int parse_netmask(char *buf, u_int32_t *addr);static int parse_timeout(char *buf, int min, int max);static unsigned int parse_fwmark(char *buf);/* check the options based on the commands_v_options table */static void generic_opt_check(int command, int options);static void set_command(int *cmd, const int newcmd);static void set_option(unsigned int *options, unsigned int option);static void tryhelp_exit(const char *program, const int exit_status);static void usage_exit(const char *program, const int exit_status);static void version_exit(int exit_status);static void version(FILE *stream);static void fail(int err, char *msg, ...);/* various listing functions */static void list_conn(unsigned int format);static void list_service(ipvs_service_t *svc, unsigned int format);static void list_all(unsigned int format);static void list_timeout(void);static void list_daemon(void);static int modprobe_ipvs(void);static void check_ipvs_version(void);static int process_options(int argc, char **argv, int reading_stdin);int main(int argc, char **argv){	int result;	if (ipvs_init()) {		/* try to insmod the ip_vs module if ipvs_init failed */		if (modprobe_ipvs() || ipvs_init())			fail(2, "Can't initialize ipvs: %s\n"				"Are you sure that IP Virtual Server is "				"built in the kernel or as module?",			     ipvs_strerror(errno));	}	/* warn the user if the IPVS version is out of date */	check_ipvs_version();	/* list the table if there is no other arguement */	if (argc == 1){		list_all(FMT_NONE);		ipvs_close();		return 0;	}	/* process command line arguments */	result = process_options(argc, argv, 0);	ipvs_close();	return result;}#ifdef HAVE_POPTstatic intparse_options(int argc, char **argv, struct ipvs_command_entry *ce,	      unsigned int *options, unsigned int *format){	int c, parse;	poptContext context;	char *optarg=NULL;	struct poptOption options_table[] = {		{"add-service", 'A', POPT_ARG_NONE, NULL, 'A'},		{"edit-service", 'E', POPT_ARG_NONE, NULL, 'E'},		{"delete-service", 'D', POPT_ARG_NONE, NULL, 'D'},		{"clear", 'C', POPT_ARG_NONE, NULL, 'C'},		{"list", 'L', POPT_ARG_NONE, NULL, 'L'},		{"list", 'l', POPT_ARG_NONE, NULL, 'l'},		{"zero", 'Z', POPT_ARG_NONE, NULL, 'Z'},		{"add-server", 'a', POPT_ARG_NONE, NULL, 'a'},		{"edit-server", 'e', POPT_ARG_NONE, NULL, 'e'},		{"delete-server", 'd', POPT_ARG_NONE, NULL, 'd'},		{"set", '\0', POPT_ARG_NONE, NULL, '4'},		{"help", 'h', POPT_ARG_NONE, NULL, 'h'},		{"version", 'v', POPT_ARG_NONE, NULL, 'v'},		{"restore", 'R', POPT_ARG_NONE, NULL, 'R'},		{"save", 'S', POPT_ARG_NONE, NULL, 'S'},		{"start-daemon", '\0', POPT_ARG_STRING, &optarg, '1'},		{"stop-daemon", '\0', POPT_ARG_STRING, &optarg, '2'},		{"tcp-service", 't', POPT_ARG_STRING, &optarg, 't'},		{"udp-service", 'u', POPT_ARG_STRING, &optarg, 'u'},		{"fwmark-service", 'f', POPT_ARG_STRING, &optarg, 'f'},		{"scheduler", 's', POPT_ARG_STRING, &optarg, 's'},		{"persistent", 'p', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL,		 &optarg, 'p'},		{"netmask", 'M', POPT_ARG_STRING, &optarg, 'M'},		{"real-server", 'r', POPT_ARG_STRING, &optarg, 'r'},		{"masquerading", 'm', POPT_ARG_NONE, NULL, 'm'},		{"ipip", 'i', POPT_ARG_NONE, NULL, 'i'},		{"gatewaying", 'g', POPT_ARG_NONE, NULL, 'g'},		{"weight", 'w', POPT_ARG_STRING, &optarg, 'w'},		{"u-threshold", 'x', POPT_ARG_STRING, &optarg, 'x'},		{"l-threshold", 'y', POPT_ARG_STRING, &optarg, 'y'},		{"numeric", 'n', POPT_ARG_NONE, NULL, 'n'},		{"connection", 'c', POPT_ARG_NONE, NULL, 'c'},		{"mcast-interface", '\0', POPT_ARG_STRING, &optarg, '3'},		{"syncid", '\0', POPT_ARG_STRING, &optarg, 'I'},		{"timeout", '\0', POPT_ARG_NONE, NULL, '5'},		{"daemon", '\0', POPT_ARG_NONE, NULL, '6'},		{"stats", '\0', POPT_ARG_NONE, NULL, '7'},		{"rate", '\0', POPT_ARG_NONE, NULL, '8'},		{"thresholds", '\0', POPT_ARG_NONE, NULL, '9'},		{"persistent-conn", '\0', POPT_ARG_NONE, NULL, 'P'},		{"sort", '\0', POPT_ARG_NONE, NULL, '0'},		{"exact", 'X', POPT_ARG_NONE, NULL, 'X'},		{NULL, 0, 0, NULL, 0}	};	context = poptGetContext("ipvsadm", argc, (const char **)argv,				 options_table, 0);	if ((c = poptGetNextOpt(context)) < 0)		tryhelp_exit(argv[0], -1);	switch (c) {	case 'A':		set_command(&ce->cmd, CMD_ADD);		break;	case 'E':		set_command(&ce->cmd, CMD_EDIT);		break;	case 'D':		set_command(&ce->cmd, CMD_DEL);		break;	case 'a':		set_command(&ce->cmd, CMD_ADDDEST);		break;	case 'e':		set_command(&ce->cmd, CMD_EDITDEST);		break;	case 'd':		set_command(&ce->cmd, CMD_DELDEST);		break;	case 'C':		set_command(&ce->cmd, CMD_FLUSH);		break;	case 'L':	case 'l':		set_command(&ce->cmd, CMD_LIST);		break;	case 'Z':		set_command(&ce->cmd, CMD_ZERO);		break;	case '4':		set_command(&ce->cmd, CMD_TIMEOUT);		break;	case 'R':		set_command(&ce->cmd, CMD_RESTORE);		break;	case 'S':		set_command(&ce->cmd, CMD_SAVE);		break;	case '1':		set_command(&ce->cmd, CMD_STARTDAEMON);		if (!strcmp(optarg, "master"))			ce->daemon.state = IP_VS_STATE_MASTER;		else if (!strcmp(optarg, "backup"))			ce->daemon.state = IP_VS_STATE_BACKUP;		else fail(2, "illegal start-daemon parameter specified");		break;	case '2':		set_command(&ce->cmd, CMD_STOPDAEMON);		if (!strcmp(optarg, "master"))			ce->daemon.state = IP_VS_STATE_MASTER;		else if (!strcmp(optarg, "backup"))			ce->daemon.state = IP_VS_STATE_BACKUP;		else fail(2, "illegal start_daemon specified");		break;	case 'h':		usage_exit(argv[0], 0);		break;	case 'v':		version_exit(0);		break;	default:		tryhelp_exit(argv[0], -1);	}	while ((c=poptGetNextOpt(context)) >= 0){		switch (c) {		case 't':		case 'u':			set_option(options, OPT_SERVICE);			ce->svc.protocol =				(c=='t' ? IPPROTO_TCP : IPPROTO_UDP);			parse = parse_service(optarg,					      ce->svc.protocol,					      &ce->svc.addr,					      &ce->svc.port);			if (!(parse & SERVICE_ADDR))				fail(2, "illegal virtual server "

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -