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

📄 ipvsadm.c

📁 实现了集群的实现 完成了资源负载平衡等问题
💻 C
📖 第 1 页 / 共 4 页
字号:
	ce.dest.weight = 1;	/* Set direct routing as default forwarding method */	ce.dest.conn_flags = IP_VS_CONN_F_DROUTE;	/* Set the default persistent granularity to /32 mask */	ce.svc.netmask = ((u_int32_t) 0xffffffff);	if (parse_options(argc, argv, &ce, &options, &format))		return -1;	generic_opt_check(ce.cmd, options);	if (ce.cmd == CMD_ADD || ce.cmd == CMD_EDIT) {		/* Make sure that port zero service is persistent */		if (!ce.svc.fwmark && !ce.svc.port &&		    (ce.svc.flags != IP_VS_SVC_F_PERSISTENT))			fail(2, "Zero port specified "			     "for non-persistent service");		/* Set the default scheduling algorithm if not specified */		if (strlen(ce.svc.sched_name) == 0)			strcpy(ce.svc.sched_name, DEF_SCHED);	}	if (ce.cmd == CMD_STARTDAEMON && strlen(ce.daemon.mcast_ifn) == 0)		strcpy(ce.daemon.mcast_ifn, DEF_MCAST_IFN);	if (ce.cmd == CMD_ADDDEST || ce.cmd == CMD_EDITDEST) {		/*		 * The destination port must be equal to the service port		 * if the IP_VS_CONN_F_TUNNEL or IP_VS_CONN_F_DROUTE is set.		 * Don't worry about this if fwmark is used.		 */		if (!ce.svc.fwmark &&		    (ce.dest.conn_flags == IP_VS_CONN_F_TUNNEL		     || ce.dest.conn_flags == IP_VS_CONN_F_DROUTE))			ce.dest.port = ce.svc.port;	}	switch (ce.cmd) {	case CMD_LIST:		if ((options & OPT_CONNECTION ||		     options & OPT_TIMEOUT || options & OPT_DAEMON) &&		    (options & OPT_STATS ||		     options & OPT_PERSISTENTCONN ||		     options & OPT_RATE || options & OPT_THRESHOLDS))			fail(2, "options conflicts in the list command");		if (options & OPT_CONNECTION)			list_conn(format);		else if (options & OPT_SERVICE)			list_service(&ce.svc, format);		else if (options & OPT_TIMEOUT)			list_timeout();		else if (options & OPT_DAEMON)			list_daemon();		else			list_all(format);		return 0;	case CMD_RESTORE:		return restore_table(argc, argv, reading_stdin);	case CMD_SAVE:		format |= FMT_RULE;		list_all(format);		return 0;	case CMD_FLUSH:		result = ipvs_flush();		break;	case CMD_ADD:		result = ipvs_add_service(&ce.svc);		break;	case CMD_EDIT:		result = ipvs_update_service(&ce.svc);		break;	case CMD_DEL:		result = ipvs_del_service(&ce.svc);		break;	case CMD_ZERO:		result = ipvs_zero_service(&ce.svc);		break;	case CMD_ADDDEST:		result = ipvs_add_dest(&ce.svc, &ce.dest);		break;	case CMD_EDITDEST:		result = ipvs_update_dest(&ce.svc, &ce.dest);		break;	case CMD_DELDEST:		result = ipvs_del_dest(&ce.svc, &ce.dest);		break;	case CMD_TIMEOUT:		result = ipvs_set_timeout(&ce.timeout);		break;	case CMD_STARTDAEMON:		result = ipvs_start_daemon(&ce.daemon);		break;	case CMD_STOPDAEMON:		result = ipvs_stop_daemon(&ce.daemon);	}	if (result)		fprintf(stderr, "%s\n", ipvs_strerror(errno));	return result;}static int string_to_number(const char *s, int min, int max){	long number;	char *end;	errno = 0;	number = strtol(s, &end, 10);	if (*end == '\0' && end != s) {		/* We parsed a number, let's see if we want this. */		if (errno != ERANGE && min <= number && number <= max)			return number;	}	return -1;}/* * Parse the timeout value. */static int parse_timeout(char *buf, int min, int max){	int i;	/* it is just for parsing timeout of persistent service */	if (buf == NULL)		return IPVS_SVC_PERSISTENT_TIMEOUT;	if ((i=string_to_number(buf, min, max)) == -1)		fail(2, "invalid timeout value `%s' specified", buf);	return i;}/* * Parse IP fwmark from the argument. */static unsigned int parse_fwmark(char *buf){	unsigned long l;	char *end;	errno = 0;	l = strtol(buf, &end, 10);	if (*end != '\0' || end == buf ||	    errno == ERANGE || l <= 0 || l > UINT_MAX)		fail(2, "invalid fwmark value `%s' specified", buf);	return l;}/* * Get netmask. * Return 0 if failed, *	  1 if addr read */static int parse_netmask(char *buf, u_int32_t *addr){	struct in_addr inaddr;	if(buf == NULL)		return 0;	if (inet_aton(buf, &inaddr) != 0)		*addr = inaddr.s_addr;	else if (host_to_addr(buf, &inaddr) != -1)		*addr = inaddr.s_addr;	else		return 0;	return 1;}/* * Get IP address and port from the argument. * Result is a logical or of * SERVICE_NONE:   no service elements set/error * SERVICE_ADDR:   addr set * SERVICE_PORT:   port set */static intparse_service(char *buf, u_int16_t proto, u_int32_t *addr, u_int16_t *port){	char *portp;	long portn;	int result=SERVICE_NONE;	struct in_addr inaddr;	if(buf==NULL || str_is_digit(buf))		return SERVICE_NONE;	portp = strchr(buf, ':');	if (portp != NULL)		*portp = '\0';	if (inet_aton(buf, &inaddr) != 0)		*addr = inaddr.s_addr;	else if (host_to_addr(buf, &inaddr) != -1)		*addr = inaddr.s_addr;	else		return SERVICE_NONE;	result |= SERVICE_ADDR;	if (portp != NULL){		result |= SERVICE_PORT;		if ((portn=string_to_number(portp+1, 0, 65535)) != -1)			*port = htons(portn);		else if ((portn=service_to_port(portp+1, proto)) != -1)			*port = htons(portn);		else			return SERVICE_NONE;	}	return result;}static voidgeneric_opt_check(int command, int options){	int i, j;	int last = 0, count = 0;	/* Check that commands are valid with options. */	i = command - CMD_NONE -1;	for (j = 0; j < NUMBER_OF_OPT; j++) {		if (!(options & (1<<j))) {			if (commands_v_options[i][j] == '+')				fail(2, "You need to supply the '%s' "				     "option for the '%s' command",				     optnames[j], cmdnames[i]);		} else {			if (commands_v_options[i][j] == 'x')				fail(2, "Illegal '%s' option with "				     "the '%s' command",				     optnames[j], cmdnames[i]);			if (commands_v_options[i][j] == '1') {				count++;				if (count == 1) {					last = j;					continue;				}				fail(2, "The option '%s' conflicts with the "				     "'%s' option in the '%s' command",				     optnames[j], optnames[last], cmdnames[i]);			}		}	}}static inline const char *opt2name(int option){	const char **ptr;	for (ptr = optnames; option > 1; option >>= 1, ptr++);	return *ptr;}static voidset_command(int *cmd, const int newcmd){	if (*cmd != CMD_NONE)		fail(2, "multiple commands specified");	*cmd = newcmd;}static voidset_option(unsigned int *options, unsigned int option){	if (*options & option)		fail(2, "multiple '%s' options specified", opt2name(option));	*options |= option;}static void tryhelp_exit(const char *program, const int exit_status){	fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n",		program, program);	exit(exit_status);}static void usage_exit(const char *program, const int exit_status){	FILE *stream;	if (exit_status != 0)		stream = stderr;	else		stream = stdout;	version(stream);	fprintf(stream,		"Usage:\n"		"  %s -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]\n"		"  %s -D -t|u|f service-address\n"		"  %s -C\n"		"  %s -R\n"		"  %s -S [-n]\n"		"  %s -a|e -t|u|f service-address -r server-address [options]\n"		"  %s -d -t|u|f service-address -r server-address\n"		"  %s -L|l [options]\n"		"  %s -Z [-t|u|f service-address]\n"		"  %s --set tcp tcpfin udp\n"		"  %s --start-daemon state [--mcast-interface interface] [--syncid sid]\n"		"  %s --stop-daemon state\n"		"  %s -h\n\n",		program, program, program,		program, program, program, program, program,		program, program, program, program, program);	fprintf(stream,		"Commands:\n"		"Either long or short options are allowed.\n"		"  --add-service     -A        add virtual service with options\n"		"  --edit-service    -E        edit virtual service with options\n"		"  --delete-service  -D        delete virtual service\n"		"  --clear           -C        clear the whole table\n"		"  --restore         -R        restore rules from stdin\n"		"  --save            -S        save rules to stdout\n"		"  --add-server      -a        add real server with options\n"		"  --edit-server     -e        edit real server with options\n"		"  --delete-server   -d        delete real server\n"		"  --list            -L|-l     list the table\n"		"  --zero            -Z        zero counters in a service or all services\n"		"  --set tcp tcpfin udp        set connection timeout values\n"		"  --start-daemon              start connection sync daemon\n"		"  --stop-daemon               stop connection sync daemon\n"		"  --help            -h        display this help message\n\n"		);	fprintf(stream,		"Options:\n"		"  --tcp-service  -t service-address   service-address is host[:port]\n"		"  --udp-service  -u service-address   service-address is host[:port]\n"		"  --fwmark-service  -f fwmark         fwmark is an integer greater than zero\n"		"  --scheduler    -s scheduler         one of " SCHEDULERS ",\n"		"                                      the default scheduler is %s.\n"		"  --persistent   -p [timeout]         persistent service\n"		"  --netmask      -M netmask           persistent granularity mask\n"		"  --real-server  -r server-address    server-address is host (and port)\n"		"  --gatewaying   -g                   gatewaying (direct routing) (default)\n"		"  --ipip         -i                   ipip encapsulation (tunneling)\n"		"  --masquerading -m                   masquerading (NAT)\n"		"  --weight       -w weight            capacity of real server\n"		"  --u-threshold  -x uthreshold        upper threshold of connections\n"		"  --l-threshold  -y lthreshold        lower threshold of connections\n"		"  --mcast-interface interface         multicast interface for connection sync\n"		"  --syncid sid                        syncid for connection sync (default=255)\n"		"  --connection   -c                   output of current IPVS connections\n"		"  --timeout                           output of timeout (tcp tcpfin udp)\n"		"  --daemon                            output of daemon information\n"		"  --stats                             output of statistics information\n"		"  --rate                              output of rate information\n"		"  --exact                             expand numbers (display exact values)\n"		"  --thresholds                        output of thresholds information\n"		"  --persistent-conn                   output of persistent connection info\n"		"  --sort                              sorting output of service/server entries\n"		"  --numeric      -n                   numeric output of addresses and ports\n",		DEF_SCHED);	exit(exit_status);}static void version_exit(const int exit_status){	FILE *stream;	if (exit_status != 0)		stream = stderr;	else		stream = stdout;	version(stream);	exit(exit_status);}static void version(FILE *stream){	fprintf(stream,		"ipvsadm " IPVSADM_VERSION " (compiled with "		IPVS_OPTION_PROCESSING " and IPVS v%d.%d.%d)\n",		NVERSION(IP_VS_VERSION_CODE));}static void fail(int err, char *msg, ...){	va_list args;	va_start(args, msg);	vfprintf(stderr, msg, args);	va_end(args);	fprintf(stderr, "\n");	exit(err);}static int modprobe_ipvs(void){	char *argv[] = { "/sbin/modprobe", "--", "ip_vs", NULL };	int child;	int status;	int rc;	if (!(child = fork())) {		execv(argv[0], argv);		exit(1);	}	rc = waitpid(child, &status, 0);	if (!WIFEXITED(status) || WEXITSTATUS(status)) {		return 1;	}	return 0;}static void check_ipvs_version(void){	/* verify the IPVS version */	if (ipvs_info.version <	    IPVS_VERSION(MINIMUM_IPVS_VERSION_MAJOR,			 MINIMUM_IPVS_VERSION_MINOR,			 MINIMUM_IPVS_VERSION_PATCH)) {		fprintf(stderr,			"Warning: IPVS version mismatch: \n"			"  Kernel compiled with IPVS version %d.%d.%d\n"			"  ipvsadm " IPVSADM_VERSION_NO			"  requires minimum IPVS version %d.%d.%d\n\n",			NVERSION(ipvs_info.version),			MINIMUM_IPVS_VERSION_MAJOR,			MINIMUM_IPVS_VERSION_MINOR,			MINIMUM_IPVS_VERSION_PATCH);	}}static void print_conn(char *buf, unsigned int format){	char            protocol[8];	unsigned short  proto;	struct in_addr  caddr;	unsigned short  cport;	struct in_addr  vaddr;	unsigned short  vport;	struct in_addr  daddr;	unsigned short  dport;	char            state[16];	unsigned int    expires;

⌨️ 快捷键说明

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