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

📄 rpp.c

📁 OpenPBS
💻 C
📖 第 1 页 / 共 5 页
字号:
/**         OpenPBS (Portable Batch System) v2.3 Software License* * Copyright (c) 1999-2002 Veridian Information Solutions, Inc.* All rights reserved.* * ---------------------------------------------------------------------------* For a license to use or redistribute the OpenPBS software under conditions* other than those described below, or to purchase support for this software,* please contact Veridian Systems, PBS Products Department ("Licensor") at:* *    www.OpenPBS.org  +1 650 967-4675                  sales@OpenPBS.org*                        877 902-4PBS (US toll-free)* ---------------------------------------------------------------------------* * This license covers use of the OpenPBS v2.3 software (the "Software") at* your site or location, and, for certain users, redistribution of the* Software to other sites and locations.  Use and redistribution of* OpenPBS v2.3 in source and binary forms, with or without modification,* are permitted provided that all of the following conditions are met.* After December 31, 2003, only conditions 3-6 must be met:* * 1. Commercial and/or non-commercial use of the Software is permitted*    provided a current software registration is on file at www.OpenPBS.org.*    If use of this software contributes to a publication, product, or*    service, proper attribution must be given; see www.OpenPBS.org/credit.html* * 2. Redistribution in any form is only permitted for non-commercial,*    non-profit purposes.  There can be no charge for the Software or any*    software incorporating the Software.  Further, there can be no*    expectation of revenue generated as a consequence of redistributing*    the Software.* * 3. Any Redistribution of source code must retain the above copyright notice*    and the acknowledgment contained in paragraph 6, this list of conditions*    and the disclaimer contained in paragraph 7.* * 4. Any Redistribution in binary form must reproduce the above copyright*    notice and the acknowledgment contained in paragraph 6, this list of*    conditions and the disclaimer contained in paragraph 7 in the*    documentation and/or other materials provided with the distribution.* * 5. Redistributions in any form must be accompanied by information on how to*    obtain complete source code for the OpenPBS software and any*    modifications and/or additions to the OpenPBS software.  The source code*    must either be included in the distribution or be available for no more*    than the cost of distribution plus a nominal fee, and all modifications*    and additions to the Software must be freely redistributable by any party*    (including Licensor) without restriction.* * 6. All advertising materials mentioning features or use of the Software must*    display the following acknowledgment:* *     "This product includes software developed by NASA Ames Research Center,*     Lawrence Livermore National Laboratory, and Veridian Information *     Solutions, Inc.*     Visit www.OpenPBS.org for OpenPBS software support,*     products, and information."* * 7. DISCLAIMER OF WARRANTY* * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. ANY EXPRESS* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT* ARE EXPRESSLY DISCLAIMED.* * IN NO EVENT SHALL VERIDIAN CORPORATION, ITS AFFILIATED COMPANIES, OR THE* U.S. GOVERNMENT OR ANY OF ITS AGENCIES BE LIABLE FOR ANY DIRECT OR INDIRECT,* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.* * This license will be governed by the laws of the Commonwealth of Virginia,* without reference to its choice of law rules.*//***	Routines to communicate with UDP packets - Reliable Packet Protocol.****	This package provides for sending information in "messages"**	which are complete blocks of data which will either arrive**	complete or not at all.*/static	char	ident[] = "@(#) $RCSfile: rpp.c,v $ $Revision: 2.3.2.2.2.7 $";#if !defined(_BSD) && defined(_AIX)   /* this is needed by AIX */#define	_BSD	1#endif#include <pbs_config.h>   /* the master config generated by configure */#include	<stdio.h>#include	<stddef.h>#include	<stdlib.h>#include	<string.h>#include	<unistd.h>#include	<fcntl.h>#include	<netdb.h>#include	<errno.h>#include	<assert.h>#include	<math.h>#include	<sys/types.h>#include	<sys/file.h>#include	<sys/stat.h>#include	<sys/socket.h>#include	<sys/time.h>#include	<netinet/in.h>#include	"rpp.h"#if !defined(H_ERRNO_DECLARED)extern int h_errno;#endif/***	Boolean Constants*/#ifndef	FALSE#define	FALSE	0#endif#ifndef	TRUE#define	TRUE	1#endif/***	Turn on for debug log dump to /tmp.#define	RPPLOG	1*//***	Size-Constants for the various parts of RPP packet*/#define	RPP_PKT_SIZE	4*1024 /* max packet length, including header */#define	RPP_PKT_HEAD	26     /* Size of packet header, includes CRC */#define	RPP_HDR_SID	2      /* position of stream id in packet header */#define	RPP_HDR_SEQ	10     /* position of "sequence" in pkt header */#define	RPP_CRC_LEN	8      /* Length of CRC field in pkt header */#define RPP_PKT_CRC	(RPP_PKT_HEAD - RPP_CRC_LEN)#define	RPP_PKT_DATA	(RPP_PKT_SIZE - RPP_PKT_HEAD)/***	RPP packet-header fields****   length             field**  ========          =========**     2		type**     8		stream id**     8		sequence**     8		crc*//***	Integer codes for all the valid RPP message types*/#define	RPP_ACK		1#define	RPP_DATA	2#define	RPP_EOD		3#define	RPP_HELLO1	4#define	RPP_HELLO2	5#define	RPP_GOODBYE	6/***	Integer codes for all the valid RPP state values*/#define RPP_DEAD	-1#define	RPP_FREE 	 0#define	RPP_OPEN_PEND	 1#define	RPP_OPEN_WAIT	 2#define	RPP_CONNECT	 3#define	RPP_CLOSE_PEND	 4#define	RPP_LAST_ACK	 5#define	RPP_CLOSE_WAIT1	 6#define	RPP_CLOSE_WAIT2	 7#define	RPP_STALE	99/***	Time in seconds; packet on the master send queue is not sent more**	often than every RPP_TIMEOUT seconds.*/#define	RPP_TIMEOUT	2/***	Default number of sendto attempts on a *packet.*/#define	RPP_RETRY	10/***	Max allowed number of outstanding pkts*/#define	RPP_HIGHWATER	24/***	Several kinds of linked lists hang from each RPP stream structure.**	In particular, each stram structure has a list of send_packet**	structures.  These structures record information that's necessary for**	managing a piece of data that's being sent to the other end of the**	connection.  Besides having a pointer that links it to the next**	send_packet on the stream, a send_packet posseses a pair of pointers**	(up,down) which link the  send_packet to the master send list when**	connection sequencing has reached the point where it is now proper to**	attach it to the list (stream is fully opened).  Once on the master**	sendlist, any invocation of the rpp_send_out routine will attempt to**	transfer the send_packet's data buffer to the other end of the stream**	connection if all of the following hold:****	1) packet hasn't reached its maximum-transfer-attempt limit**	2) RPP_TIMEOUT or more seconds have elapsed since the last attempt**	3) the transfer has yet to be ACK'd by the other side.**	4) less than RPP_HIGHWATER number of non-duplicate packets are**	   un-ACK'd****	Those "send_packets" that deal with stream control**	(RPP_ACK, RPP_HELLO1, RPP_HELLO2, RPP_GOODBYE) have no**	associated data, the send_packet's data buffer is comprised**	of only the header.*/struct	send_packet {	u_char	*data;               /* points to a buffer to be transferred */	u_short	type;		     /* RPP_ACK, RPP_HELLO1, RPP_DATA, etc */	u_short	sent_out;            /* number of times sent; <= sp->retry */	int	len;                 /* size *data not counting the header */	int	index;               /* other end's stream id */	int	sequence;            /* sequential value that is placed into */                                     /* data buffer's header and is returned */                                     /* in the RPP_ACK; identifies the data */                                     /* that was transferred and now needs */                                     /* to be removed from master send list */	time_t	time_sent;	     /* time packet was last sent; zero if */				     /* it has yet to be sent */	struct	send_packet	*next;	/* next packet on stream's send list */	struct	send_packet	*up;	/* used when the send_packet is */					/* on RPP's master send list */					/* pointer to preceeding packet */	struct	send_packet	*down;	/* similar to up, but pointing to */					/* packet following this one */};/***	Hanging from an stream structure is a linked list of recv_packets**	Each recv_packet records the information necessary for managing a**	piece of data that was received from the other end of a connection.**	With the exception of RPP_GOODBYE (a surrogate RPP_EOD), pkts that deal**	with stream control (RPP_ACK,RPP_HELLO1,RPP_HELLO2,) don't ever make it**	to the stream's receive list, they are handled directly as they come**	in.  So, the only types of packets on a stream's receive list should**	be ones of type RPP_DATA, RPP_EOD, and RPP_GOODBYE.*/struct	recv_packet {	u_char	*data;		/* pointer to byte string that was sent from */				/* the other end of the stream */	u_short	type;		/* RPP_DATA, RPP_EOD or RPP_GOODBYE; i.e. a */				/* piece of the message or the end of the */				/* message (RPP_EOD or RPP_GOODBYE) */	int	len;		/* size in bytes of the received string; */				/* does not include the length of the header */	int	sequence;	/* decoded sequential number; it describes */				/* the buffer's sequential output order */				/* relative to the other buffers */	struct	recv_packet  *next;	/* pointer to next recv_packet in */					/* the linked  receive list for */					/* this stream */};/***	Each stream structure has a linked list of pend structs hanging**	from it.  This list of structs is used to manage a set of data buffers**	that may or may not all get 'packetized' and sent over to the other**	end of the connection.  Subsequent to the creation of the list of data**	buffers, the creating program decides to either commit or not commit**	the sending of this data to the other side-- done by calling the**	interface function, rpp_wcommit.  The interface function**	rpp_write doesn't send the data, it merely**	attaches the data buffer to a pending struct and links this struct to**	the stream's list of pending structs.  No transfer to the other end**	gets set in motion by calling rpp_write.****	Doing an rpp_wcommit, on the other hand, entails adjoining a header**	to each pending struct's data buffer, attaching the buffer to a**	new send_packet struct, linking the send_packet to the master send**	list, freeing the pend struct, and doing an update of the stream's**	pend_commit variable -- a running sum of the number of bytes sent**	to the other side.****	Decommiting data that was written for transfer to the other end entails**	removing and freeing the pending structs and their associated data**	buffer from the stream's pend list and, updating the stream's**	pend_attempt varable back to the byte count that is stored in its**	pend_commit variable.  Refer to relevant fields in struct stream.*/struct	pending {	u_char	*data;		/* pointer to a buffer of user data */	struct	pending	*next;	/* pointer to the next pending struct */};/***	Every stream that comes into existence during the life of the**	process gets realized on each end of the connection by a stream**	struct.  All the stream structs generated by a process are in a**	dynamic array in the process' heap area.**	Each stream is a finite state machine.*/struct	stream {	int			state;		/* state of this end of the */						/* connection; RPP_OPEN, etc */	struct	sockaddr_in	addr;		/* address of the other end; */						/* port/family/IPadrs */	struct	in_addr		*addr_array;	/* array of alternate network */						/* addresses for other end */						/* of the connection */	int			fd;		/* must be in rpp_fd_array */	int			stream_id;	/* id of other end of the */						/* connection; array position */						/* of stream struct on the */						/* other end */	int			retry;		/* sendto retry limit */	int			open_key;	/* unique bit pattern created */						/* by the end issuing the */						/* rpp_open.  It's the same */						/* same for each end of the */						/* connecton; used in setting */						/* up the stream connection */	int			msg_cnt;	/* size in bytes of current */						/* DATA/EOD/GOODBYE message */	int			send_sequence;	/* initialized to value of 1 */						/* and incremented by 1 for */						/* each packet that's added */						/* to the master send list */	struct	pending		*pend_head;	/* head and tail pointers for */	struct	pending		*pend_tail;	/* stream's pend list; see */						/* struct pend definition */	int			pend_commit;	/* total number of data bytes */						/* sent to other end connect */	int			pend_attempt;	/* total number bytes that */						/* reside in the list of */						/* pending struct buffers. */						/* pend_commit<=pend_attempt */	struct	send_packet	*send_head;	/* head and tail pointers for */	struct	send_packet	*send_tail;	/* stream's master send list */						/* see struct send_packet */	int			recv_sequence;	/* monotonic,increasing, by 1 */						/* starts from zero; A packet */						/* on the stream's recv list */						/* having a sequence number */						/* less than this value is a */						/* packet of an earlier mesg */	struct	recv_packet	*recv_head;	/* head and tail pointers for */	struct	recv_packet	*recv_tail;	/* the stream's recv list; */						/* see struct recv_packet */	int			recv_commit;	/* number of bytes from */						/* start of current message */						/* that have been accepted */						/* by the reader on this end */	int			recv_attempt;	/* number bytes, from start */						/* of current message, that */						/* have been read */};/***	Static Variables*/static	struct	stream	*stream_array = NULL;	/* pointer to stream struct */						/* dynamic array */static	int		stream_num = 0;		/* current number of stream */						/* structs in stream_array */static	int		pkts_sent = 0;		/* range: 0 - RPP_HIGHWATER; */						/* incremented with each new */						/* pkt sent; retransmissions */						/* are not counted */static	int		open_key = 0;		/* monotonicly increasing */						/* value stored in stream */						/* struct on rpp_open and */						/* passed to other end to */						/* be recorded in */						/* corresponding stream */						/* struct there */static	struct	send_packet	*top = NULL;	/* ptrs to beginning and end */static	struct	send_packet	*bottom = NULL; /* of master send list; */						/* All sent date is linked */						/* between top and bottom. *//***	Global Variables*/int		rpp_dbprt = 0;			/* controls debug printing *//***	Current file descriptor.  Any call to rpp_open will use this**	for the returned stream.*/int		rpp_fd = -1;/***	A dynamic array of socket descriptors bound to a network address.**	More than one call to rpp_bind can result in this having multiple**	entries.  The value of rpp_fd will be contained in this array.*/int		*rpp_fd_array = NULL;/***	Number of elements in rpp_fd_array*/int		rpp_fd_num = 0;/***	Number of retrys to set into each new stream.*/int		rpp_retry = RPP_RETRY;/***	Tables used by the macros I2TOH, HTOI2, I8TOH, HTOI8**	to convert 2 and 8 digit hexidecimal strings to integer and back.*/char	cval[] = {	-1, -1, -1, -1, -1, -1, -1, -1,		/* nul .. bel */	-1, -1, -1, -1, -1, -1, -1, -1,		/* bs .. si */	-1, -1, -1, -1, -1, -1, -1, -1,		/* dle .. etb */	-1, -1, -1, -1, -1, -1, -1, -1,		/* can .. us */	-1, -1, -1, -1, -1, -1, -1, -1,		/* sp .. ' */	-1, -1, -1, -1, -1, -1, -1, -1,		/* ( .. / */	 0,  1,  2,  3,  4,  5,  6,  7,		/* 0 .. 7 */	 8,  9, -1, -1, -1, -1, -1, -1,		/* 8 .. ? */	-1, 10, 11, 12, 13, 14, 15, -1,		/* @ .. G */	-1, -1, -1, -1, -1, -1, -1, -1,		/* H .. O */	-1, -1, -1, -1, -1, -1, -1, -1,		/* P .. W */	-1, -1, -1, -1, -1, -1, -1, -1,		/* X .. _ */	-1, 10, 11, 12, 13, 14, 15, -1,		/* ` .. g */	-1, -1, -1, -1, -1, -1, -1, -1,		/* h .. o */	-1, -1, -1, -1, -1, -1, -1, -1,		/* p .. w */	-1, -1, -1, -1, -1, -1, -1, -1		/* x .. del */};char	ival[] = {	'0', '1', '2', '3', '4', '5', '6', '7',	'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};/***	Conversion macros*/#define	I2TOH(i, h) \{ \	int	num = i; \	char	*str = h; \	str[1] = ival[num & 0xF]; num >>= 4 ; \	str[0] = ival[num & 0xF]; \}#define	I8TOH(i, h) \{ \	u_long	num = i; \	char	*str = h; \	str[7] = ival[num & 0xF]; num >>= 4; \	str[6] = ival[num & 0xF]; num >>= 4; \	str[5] = ival[num & 0xF]; num >>= 4; \	str[4] = ival[num & 0xF]; num >>= 4; \	str[3] = ival[num & 0xF]; num >>= 4; \	str[2] = ival[num & 0xF]; num >>= 4; \	str[1] = ival[num & 0xF]; num >>= 4; \	str[0] = ival[num & 0xF]; \}#define	HTOI2(h, i) \{ \	char	*str = h; \	int	num = 0; \	num = cval[str[0] & 0xFF]; num <<= 4; \	num |= cval[str[1] & 0xFF]; \	i = num; \}#define	HTOI8(h, i) \{ \	char	*str = h; \	u_long	num; \	num  = (long)cval[str[0] & 0x7F]; num <<= 4; \	num |= (long)cval[str[1] & 0x7F]; num <<= 4; \	num |= (long)cval[str[2] & 0x7F]; num <<= 4; \	num |= (long)cval[str[3] & 0x7F]; num <<= 4; \	num |= (long)cval[str[4] & 0x7F]; num <<= 4; \	num |= (long)cval[str[5] & 0x7F]; num <<= 4; \	num |= (long)cval[str[6] & 0x7F]; num <<= 4; \	num |= (long)cval[str[7] & 0x7F]; \	i = num; \}/***	Different print macros for use in debugging.*/

⌨️ 快捷键说明

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