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

📄 ping_group.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: ping_group.c,v 1.13 2004/10/24 13:00:13 lge Exp $ *//* * ping_group.c: ICMP-echo-based heartbeat code for heartbeat. * * This allows a group of nodes to be pinged. The group is * considered to be available if any of the nodes are available. * * Copyright (C) 2003 Horms <horms@verge.net.au> * * Based heavily on ping.c * Copyright (C) 2000 Alan Robertson <alanr@unix.sh> * * The checksum code in this file code was borrowed from the ping program. * * SECURITY NOTE:  It would be very easy for someone to masquerade as the * device that you're pinging.  If they don't know the password, all they can * do is echo back the packets that you're sending out, or send out old ones. * This does mean that if you're using such an approach, that someone could * make you think you have quorum when you don't during a cluster partition. * The danger in that seems small, but you never know ;-) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library 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 * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include <portability.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <ctype.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/param.h>#ifdef HAVE_NETINET_IN_SYSTM_H#	include <netinet/in_systm.h>#endif /* HAVE_NETINET_IN_SYSTM_H */#ifdef HAVE_NETINET_IP_H#	include <netinet/ip.h>#endif /* HAVE_NETINET_IP_H */#include <netinet/ip_icmp.h>#ifdef HAVE_NETINET_IP_H#	include <netinet/ip.h>#endif /* HAVE_NETINET_IP_H */#ifdef HAVE_NETINET_IP_VAR_H#	include <netinet/ip_var.h>#endif /* HAVE_NETINET_IP_VAR_H */#ifdef HAVE_NETINET_IP_COMPAT_H#	include <netinet/ip_compat.h>#endif /* HAVE_NETINET_IP_COMPAT_H */#ifdef HAVE_NETINET_IP_FW_H#	include <netinet/ip_fw.h>#endif /* HAVE_NETINET_IP_FW_H */#include <netdb.h>#include <heartbeat.h>#include <HBcomm.h>#include <clplumbing/realtime.h>#ifdef linux#	define	ICMP_HDR_SZ	sizeof(struct icmphdr)	/* 8 */#else#	define	ICMP_HDR_SZ	8#endif#define PIL_PLUGINTYPE          HB_COMM_TYPE#define PIL_PLUGINTYPE_S        HB_COMM_TYPE_S#define PIL_PLUGIN              ping_group#define PIL_PLUGIN_S            "ping_group"#define PIL_PLUGINLICENSE	LICENSE_LGPL#define PIL_PLUGINLICENSEURL	URL_LGPL#include <pils/plugin.h>#define NSLOT			128              /* How old ping sequence						   numbers can be to still						   count */typedef struct ping_group_node ping_group_node_t;struct ping_group_node {        struct sockaddr_in      addr;   	/* ping addr */	ping_group_node_t	*next;};typedef struct {	int			ident;		/* heartbeat pid */        int    			sock;		/* ping socket */	ping_group_node_t	*node;	size_t			nnode;	int			slot[NSLOT];	int			iseq;		/* sequence number */} ping_group_private_t;static int   		ping_group_parse(const char *line);static int		ping_group_open (struct hb_media* mp);static int		ping_group_close (struct hb_media* mp);static void*		ping_group_read (struct hb_media* mp, int* lenp);static int		ping_group_write (struct hb_media* mp					  ,void* msg, int len);static struct hb_media * ping_group_new(const char *name);static int		in_cksum (u_short * buf, size_t nbytes);static int		ping_group_mtype(char **buffer);static int		ping_group_descr(char **buffer);static int		ping_group_isping(void);#define		ISPINGGROUPOBJECT(mp)	                                     \			((mp) && ((mp)->vf == (void*)&ping_group_ops))#define		PINGGROUPASSERT(mp)	g_assert(ISPINGGROUPOBJECT(mp))static struct hb_media_fns ping_group_ops ={	NULL,		  /* Create single object function */	ping_group_parse, /* whole-line parse function */	ping_group_open,	ping_group_close,	ping_group_read,	ping_group_write,	ping_group_mtype,	ping_group_descr,	ping_group_isping,};PIL_PLUGIN_BOILERPLATE2("1.0", Debug)static const PILPluginImports*  PluginImports;static PILPlugin*               OurPlugin;static PILInterface*		OurInterface;static struct hb_media_imports*	OurImports;static void*			interfprivate;#define LOG	PluginImports->log#define MALLOC	PluginImports->alloc#define STRDUP  PluginImports->mstrdup#define FREE	PluginImports->mfreePIL_rcPIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports);PIL_rcPIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports){	/* Force the compiler to do a little type checking */	(void)(PILPluginInitFun)PIL_PLUGIN_INIT;	PluginImports = imports;	OurPlugin = us;	/* Register ourself as a plugin */	imports->register_plugin(us, &OurPIExports);  	/*  Register our interface implementation */ 	return imports->register_interface(us, PIL_PLUGINTYPE_S	,	PIL_PLUGIN_S	,	&ping_group_ops	,	NULL		/*close */	,	&OurInterface	,	(void*)&OurImports	,	interfprivate); }static intping_group_mtype(char **buffer) { 		*buffer = STRDUP(PIL_PLUGIN_S);	if (!*buffer) {		return 0;	}	return strlen(*buffer);}static intping_group_descr(char **buffer) { 	*buffer = STRDUP("ping group membership");	if (!*buffer) {		return 0;	}	return strlen(*buffer);}/* Yes, a ping device */static intping_group_isping(void) {	return 1;}static ping_group_node_t *new_ping_group_node(const char *host){	ping_group_node_t* node;	node = (ping_group_node_t*)MALLOC(sizeof(ping_group_node_t));	if(!node) {		return(NULL);	}	memset(node, 0, sizeof(ping_group_node_t));#ifdef HAVE_SOCKADDR_IN_SIN_LEN	node->addr.sin_len = sizeof(struct sockaddr_in);#endif	node->addr.sin_family = AF_INET;	if (inet_pton(AF_INET, host, (void *)&node->addr.sin_addr) <= 0) {		struct hostent *hp;		hp = gethostbyname(host);		if (hp == NULL) {			PILCallLog(LOG, PIL_CRIT, "unknown host: %s: %s"			,	host, strerror(errno));			FREE(node);			return NULL;		}		node->addr.sin_family = hp->h_addrtype;		memcpy(&node->addr.sin_addr, hp->h_addr, hp->h_length);	}	return(node);}static intping_group_add_node(struct hb_media* media, const char *host){	ping_group_private_t *priv;	ping_group_node_t *node;	PINGGROUPASSERT(media);	priv = (ping_group_private_t *)media->pd;	node = new_ping_group_node(host);	if(!node) {		return(HA_FAIL);	}	node->next = priv->node;	priv->node = node;	priv->nnode++;	return(HA_OK);}/* *	Create new ping heartbeat object  *	Name of host is passed as a parameter */static struct hb_media *ping_group_new(const char *name){	ping_group_private_t*	priv;	struct hb_media *	media;	char *			tmp;	priv = (ping_group_private_t*)MALLOC(sizeof(ping_group_private_t));	if(!priv) {		return(NULL);	}	memset(priv, 0, sizeof(ping_group_private_t));	priv->ident = getpid() & 0xFFFF;	media = (struct hb_media *) MALLOC(sizeof(struct hb_media));	if(!media) {		FREE(priv);		return(NULL);	}	media->pd = (void*)priv;	tmp = STRDUP(name);	if(!tmp) {		FREE(priv);		FREE(media);		return(NULL);	}	media->name = tmp;	add_node(tmp, PINGNODE_I);	/* Fake it so that PINGGROUPASSERT() will work	 * before the media is registered */	media->vf = (void*)&ping_group_ops;	return(media);}static voidping_group_destroy_data(struct hb_media* media){	ping_group_private_t*	priv;	ping_group_node_t *	node;	PINGGROUPASSERT(media);        priv = (ping_group_private_t *)media->pd;	while(priv->node) {		node = priv->node;		priv->node = node->next;		FREE(node);	}}static voidping_group_destroy(struct hb_media* media){	ping_group_private_t*	priv;	PINGGROUPASSERT(media);        priv = (ping_group_private_t *)media->pd;	ping_group_destroy_data(media);	FREE(priv);	media->pd = NULL;	/* XXX: How can we free this? Should media->name really be const?	 * And on the same topic, how are media unregistered / freed ? */	/*	tmp = (char *)media->name;	FREE(tmp);	media->name = NULL;	*/}/* *	Close UDP/IP broadcast heartbeat interface */static intping_group_close(struct hb_media* mp){	ping_group_private_t * ei;	int	rc = HA_OK;	PINGGROUPASSERT(mp);	ei = (ping_group_private_t *) mp->pd;	if (ei->sock >= 0) {		if (close(ei->sock) < 0) {			rc = HA_FAIL;		}	}	ping_group_destroy_data(mp);	return(rc);}/* * Receive a heartbeat ping reply packet. */static void *ping_group_read(struct hb_media* mp, int *lenp){		ping_group_private_t *	ei;	union {		char		cbuf[MAXLINE+ICMP_HDR_SZ];

⌨️ 快捷键说明

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