Index: src/tcp6.c
===================================================================
RCS file: src/tcp6.c
diff -N src/tcp6.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/tcp6.c	9 Sep 2004 08:35:07 -0000	1.1
@@ -0,0 +1,444 @@
+/*****************************************************************************/
+/* "NetPIPE" -- Network Protocol Independent Performance Evaluator.          */
+/* Copyright 1997, 1998 Iowa State University Research Foundation, Inc.      */
+/*                                                                           */
+/* 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.  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.   */
+/*                                                                           */
+/* TCP6 extension Copyright 2004 George V. Neville-Neil and Neville-Neil     */
+/* Consulting                                                                */
+/*                                                                           */
+/*     * tcp6.c         ---- TCP over IPv6 calls source                      */
+/*     * tcp.h          ---- Include file for TCP6 calls and data structs    */
+/*****************************************************************************/
+#include    "netpipe.h"
+
+#if defined (MPLITE)
+#include "mplite.h"
+#endif
+
+
+int doing_reset = 0;
+
+void Init(ArgStruct *p, int* pargc, char*** pargv)
+{
+    p->reset_conn = 0; /* Default to not resetting connection */
+    p->prot.sndbufsz = p->prot.rcvbufsz = 0;
+    /* The transmitter will be set using the -h host flag. */
+    p->tr = 0;
+    p->rcv = 1;
+}
+
+void Setup(ArgStruct *p)
+{
+    int one = 1;
+    int sockfd = -1;
+    /* ptr to sockaddr_in in ArgStruct */
+    struct sockaddr_in6 *lsin1, *lsin2;      
+    
+    char *host;
+    struct hostent *hp;
+    struct protoent *proto;
+    int send_size, recv_size, sizeofint = sizeof(int);
+	
+    host = p->host;                           /* copy ptr to hostname */ 
+	
+    lsin1 = &(p->prot.sin1);
+    lsin2 = &(p->prot.sin2);
+	
+    bzero((char *) lsin1, sizeof(*lsin1));
+    bzero((char *) lsin2, sizeof(*lsin2));
+
+    if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0){
+	printf("NetPIPE: can't open stream socket! errno=%d\n", errno);
+	exit(-4);
+    }
+
+    if(!(proto = getprotobyname("tcp"))){
+	printf("NetPIPE: protocol 'tcp' unknown!\n");
+	exit(555);
+    }
+
+    /* Attempt to set TCP_NODELAY */
+
+    if(setsockopt(sockfd, proto->p_proto, TCP_NODELAY, &one, sizeof(one)) < 0)
+    {
+	printf("NetPIPE: setsockopt: TCP_NODELAY failed! errno=%d\n", errno);
+	exit(556);
+    }
+
+    /* If requested, set the send and receive buffer sizes */
+
+    if(p->prot.sndbufsz > 0)
+    {
+	if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 
+		      sizeof(p->prot.sndbufsz)) < 0)
+	{
+	    printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
+	    printf("You may have asked for a buffer larger than the system can handle\n");
+	    exit(556);
+	}
+	if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
+		      sizeof(p->prot.rcvbufsz)) < 0)
+	{
+	    printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
+	    printf("You may have asked for a buffer larger than the system can handle\n");
+	    exit(556);
+	}
+    }
+    getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
+	       (char *) &send_size, (void *) &sizeofint);
+    getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
+	       (char *) &recv_size, (void *) &sizeofint);
+ 
+    if(!doing_reset) {
+	fprintf(stderr,"Send and receive buffers are %d and %d bytes\n",
+		send_size, recv_size);
+	fprintf(stderr, "(A bug in Linux doubles the requested buffer sizes)\n");
+    }
+
+    if( p->tr ) {                             /* Primary transmitter */
+
+	lsin1->sin6_family = AF_INET6;
+
+	/* First attempt to convert the string to an IPv6 */
+	/* address. */
+	/* If the user supplied a real host name this will fail and */
+  	/* we'll then do a name lookup. */
+
+	if (inet_pton(AF_INET6, host, &lsin1->sin6_addr) == 0)
+	{
+	    if ((hp = gethostbyname2(host, AF_INET6)) == NULL)
+	    {
+		printf("NetPIPE: invalid hostname '%s'\n", host);
+		exit(-5);
+	    }
+
+	    if (hp->h_addrtype != AF_INET6) 
+	    {
+		printf("NetPIPE: invalid hostname '%s'\n", host);
+		exit(-5);
+	    }
+	    bcopy(hp->h_addr, (char*) &(lsin1->sin6_addr), 
+		  hp->h_length);
+	}
+
+	lsin1->sin6_port = htons(p->port);
+	
+	p->commfd = sockfd;
+	
+    } else if( p->rcv ) {                     /* we are the receiver */
+	bzero((char *) lsin1, sizeof(*lsin1));
+	lsin1->sin6_family  = AF_INET6;
+	lsin1->sin6_len     = sizeof(*lsin1);
+	lsin1->sin6_port    = htons(p->port);
+	/* Setting this to all 0 is the "ANY" address. */
+	bzero(&lsin1->sin6_addr, sizeof(lsin1->sin6_addr));
+   
+	if (bind(sockfd, (struct sockaddr *) lsin1, sizeof(*lsin1)) < 0){
+	    printf("NetPIPE: server: bind on local address failed! errno=%d", errno);
+	    exit(-6);
+	}
+
+	p->servicefd = sockfd;
+    }
+    p->upper = send_size + recv_size;
+
+    establish(p);                               /* Establish connections */
+
+}   
+
+static int
+readFully(int fd, void *obuf, int len)
+{
+    int bytesLeft = len;
+    char *buf = (char *) obuf;
+    int bytesRead = 0;
+
+    while (bytesLeft > 0 &&
+	   (bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
+    {
+	bytesLeft -= bytesRead;
+	buf += bytesRead;
+    }
+    if (bytesRead <= 0) return bytesRead;
+    return len;
+}
+
+void Sync(ArgStruct *p)
+{
+    char s[] = "SyncMe", response[] = "      ";
+
+    if (write(p->commfd, s, strlen(s)) < 0 ||           /* Write to nbor */
+	readFully(p->commfd, response, strlen(s)) < 0)  /* Read from nbor */
+    {
+	perror("NetPIPE: error writing or reading synchronization string");
+	exit(3);
+    }
+    if (strncmp(s, response, strlen(s)))
+    {
+	fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", response);
+	exit(3);
+    }
+}
+
+void PrepareToReceive(ArgStruct *p)
+{
+    /*
+      The Berkeley sockets interface doesn't have a method to pre-post
+      a buffer for reception of data.
+    */
+}
+
+void SendData(ArgStruct *p)
+{
+    int bytesWritten, bytesLeft;
+    char *q;
+
+    bytesLeft = p->bufflen;
+    bytesWritten = 0;
+    q = p->s_ptr;
+    while (bytesLeft > 0 &&
+	   (bytesWritten = write(p->commfd, q, bytesLeft)) > 0)
+    {
+	bytesLeft -= bytesWritten;
+	q += bytesWritten;
+    }
+    if (bytesWritten == -1)
+    {
+	printf("NetPIPE: write: error encountered, errno=%d\n", errno);
+	exit(401);
+    }
+}
+
+void RecvData(ArgStruct *p)
+{
+    int bytesLeft;
+    int bytesRead;
+    char *q;
+
+    bytesLeft = p->bufflen;
+    bytesRead = 0;
+    q = p->r_ptr;
+    while (bytesLeft > 0 &&
+	   (bytesRead = read(p->commfd, q, bytesLeft)) > 0)
+    {
+	bytesLeft -= bytesRead;
+	q += bytesRead;
+    }
+    if (bytesLeft > 0 && bytesRead == 0)
+    {
+	printf("NetPIPE: \"end of file\" encountered on reading from socket\n");
+    }
+    else if (bytesRead == -1)
+    {
+	printf("NetPIPE: read: error encountered, errno=%d\n", errno);
+	exit(401);
+    }
+}
+
+/* uint32_t is used to insure that the integer size is the same even in tests 
+ * between 64-bit and 32-bit architectures. */
+
+void SendTime(ArgStruct *p, double *t)
+{
+    uint32_t ltime, ntime;
+
+    /*
+      Multiply the number of seconds by 1e8 to get time in 0.01 microseconds
+      and convert value to an unsigned 32-bit integer.
+    */
+    ltime = (uint32_t)(*t * 1.e8);
+
+    /* Send time in network order */
+    ntime = htonl(ltime);
+    if (write(p->commfd, (char *)&ntime, sizeof(uint32_t)) < 0)
+    {
+	printf("NetPIPE: write failed in SendTime: errno=%d\n", errno);
+	exit(301);
+    }
+}
+
+void RecvTime(ArgStruct *p, double *t)
+{
+    uint32_t ltime, ntime;
+    int bytesRead;
+
+    bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(uint32_t));
+    if (bytesRead < 0)
+    {
+	printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno);
+	exit(302);
+    }
+    else if (bytesRead != sizeof(uint32_t))
+    {
+	fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n",
+		bytesRead);
+	exit(303);
+    }
+    ltime = ntohl(ntime);
+
+    /* Result is ltime (in microseconds) divided by 1.0e8 to get seconds */
+
+    *t = (double)ltime / 1.0e8;
+}
+
+void SendRepeat(ArgStruct *p, int rpt)
+{
+    uint32_t lrpt, nrpt;
+
+    lrpt = rpt;
+    /* Send repeat count as a long in network order */
+    nrpt = htonl(lrpt);
+    if (write(p->commfd, (void *) &nrpt, sizeof(uint32_t)) < 0)
+    {
+	printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno);
+	exit(304);
+    }
+}
+
+void RecvRepeat(ArgStruct *p, int *rpt)
+{
+    uint32_t lrpt, nrpt;
+    int bytesRead;
+
+    bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(uint32_t));
+    if (bytesRead < 0)
+    {
+	printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno);
+	exit(305);
+    }
+    else if (bytesRead != sizeof(uint32_t))
+    {
+	fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n",
+		bytesRead);
+	exit(306);
+    }
+    lrpt = ntohl(nrpt);
+
+    *rpt = lrpt;
+}
+
+void establish(ArgStruct *p)
+{
+    int one = 1;
+    socklen_t clen;
+    struct protoent *proto;
+
+    clen = (socklen_t) sizeof(p->prot.sin2);
+
+    if( p->tr ){
+
+	while( connect(p->commfd, (struct sockaddr *) &(p->prot.sin1),
+		       sizeof(p->prot.sin1)) < 0 ) {
+
+	    /* If we are doing a reset and we get a connection refused from
+	     * the connect() call, assume that the other node has not yet
+	     * gotten to its corresponding accept() call and keep trying until
+	     * we have success.
+	     */
+	    if(!doing_reset || errno != ECONNREFUSED) {
+		printf("Client: Cannot Connect! errno=%d\n",errno);
+		exit(-10);
+	    } 
+        
+	}
+
+    } else if( p->rcv ) {
+
+	/* SERVER */
+	listen(p->servicefd, 5);
+	p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sin2), &clen);
+
+	if(p->commfd < 0){
+	    printf("Server: Accept Failed! errno=%d\n",errno);
+	    exit(-12);
+	}
+
+	/*
+	  Attempt to set TCP_NODELAY. TCP_NODELAY may or may not be propagated
+	  to accepted sockets.
+	*/
+	if(!(proto = getprotobyname("tcp"))){
+	    printf("unknown protocol!\n");
+	    exit(555);
+	}
+
+	if(setsockopt(p->commfd, proto->p_proto, TCP_NODELAY,
+		      &one, sizeof(one)) < 0)
+	{
+	    printf("setsockopt: TCP_NODELAY failed! errno=%d\n", errno);
+	    exit(556);
+	}
+
+	/* If requested, set the send and receive buffer sizes */
+	if(p->prot.sndbufsz > 0)
+	{
+/*      printf("Send and Receive Buffers on accepted socket set to %d bytes\n",*/
+/*           p->prot.sndbufsz);*/
+	    if(setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 
+			  sizeof(p->prot.sndbufsz)) < 0)
+	    {
+		printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
+		exit(556);
+	    }
+	    if(setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
+			  sizeof(p->prot.rcvbufsz)) < 0)
+	    {
+		printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
+		exit(556);
+	    }
+	}
+    }
+}
+
+void CleanUp(ArgStruct *p)
+{
+    char *quit="QUIT";
+
+    if (p->tr) {
+
+	write(p->commfd,quit, 5);
+	read(p->commfd, quit, 5);
+	close(p->commfd);
+
+    } else if( p->rcv ) {
+
+	read(p->commfd,quit, 5);
+	write(p->commfd,quit,5);
+	close(p->commfd);
+	close(p->servicefd);
+
+    }
+}
+
+
+void Reset(ArgStruct *p)
+{
+  
+    /* Reset sockets */
+
+    if(p->reset_conn) {
+
+	doing_reset = 1;
+
+	/* Close the sockets */
+
+	CleanUp(p);
+
+	/* Now open and connect new sockets */
+
+	Setup(p);
+
+    }
+
+}
+
+void AfterAlignmentInit(ArgStruct *p)
+{
+
+}
+




syntax highlighted by Code2HTML, v. 0.9.1