1b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/*****************************************************************************/ 2b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* "NetPIPE" -- Network Protocol Independent Performance Evaluator. */ 3b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* Copyright 1997, 1998 Iowa State University Research Foundation, Inc. */ 4b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* */ 5b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* This program is free software; you can redistribute it and/or modify */ 6b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* it under the terms of the GNU General Public License as published by */ 7b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* the Free Software Foundation. You should have received a copy of the */ 8b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* GNU General Public License along with this program; if not, write to the */ 94548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao/* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ 10b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* */ 11b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* * TCP.c ---- TCP calls source */ 12b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/* * TCP.h ---- Include file for TCP calls and data structs */ 13b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew/*****************************************************************************/ 14b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew#include "netpipe.h" 15b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 16354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint Setup(ArgStruct * p) 17b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 18354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int tr, one = 1; /* tr==1 if process is a transmitter */ 19354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int sockfd; 20354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sockaddr_in *lsin1, *lsin2; /* ptr to sockaddr_in in ArgStruct */ 21354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *host; 22354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct hostent *addr; 23354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct protoent *proto; 24354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 25354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao host = p->host; /* copy ptr to hostname */ 26354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao tr = p->tr; /* copy tr indicator */ 27354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 28354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1 = &(p->prot.sin1); 29354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin2 = &(p->prot.sin2); 30354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 31354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memset((char *)lsin1, 0x00, sizeof(*lsin1)); 32354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memset((char *)lsin2, 0x00, sizeof(*lsin2)); 33354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 34354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 35354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: can't open stream socket! errno=%d\n", errno); 36354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-4); 37354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 38354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 39354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!(proto = getprotobyname("tcp"))) { 40354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: protocol 'tcp' unknown!\n"); 41354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(555); 42354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 43354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 44354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Attempt to set TCP_NODELAY */ 45354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (setsockopt(sockfd, proto->p_proto, TCP_NODELAY, &one, sizeof(one)) < 46354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 0) { 47354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: setsockopt: TCP_NODELAY failed! errno=%d\n", 48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(556); 50354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 51354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 52354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* If requested, set the send and receive buffer sizes */ 53354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (p->prot.sndbufsz > 0) { 54354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Send and Receive Buffers set to %d bytes\n", 55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao p->prot.sndbufsz); 56354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (setsockopt 57354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(p->prot.sndbufsz)) < 0) { 59354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 62354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(556); 63354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (setsockopt 65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 66354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(p->prot.rcvbufsz)) < 0) { 67354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 68354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", 69354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 70354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(556); 71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 73354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 74354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (tr) { /* if client i.e., Sender */ 75354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 76354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (atoi(host) > 0) { /* Numerical IP address */ 77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_family = AF_INET; 78354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_addr.s_addr = inet_addr(host); 79354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 80354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 82354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if ((addr = gethostbyname(host)) == NULL) { 83354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: invalid hostname '%s'\n", 84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao host); 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-5); 86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_family = addr->h_addrtype; 89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memcpy((char *)&(lsin1->sin_addr.s_addr), addr->h_addr, 90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao addr->h_length); 91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_port = htons(p->port); 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { /* we are the receiver (server) */ 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao memset((char *)lsin1, 0x00, sizeof(*lsin1)); 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_family = AF_INET; 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_addr.s_addr = htonl(INADDR_ANY); 100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lsin1->sin_port = htons(p->port); 101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (bind(sockfd, (struct sockaddr *)lsin1, sizeof(*lsin1)) < 0) { 103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("NetPIPE: server: bind on local address failed! errno=%d", 105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-6); 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (tr) 112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao p->commfd = sockfd; 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao else 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao p->servicefd = sockfd; 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return (0); 11757c212c57d43b73993ce4af1224b26c810353516vapier} 118b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 119354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int readFully(int fd, void *obuf, int len) 120b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 121354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesLeft = len; 122354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *buf = (char *)obuf; 123354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesRead = 0; 124354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 125354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao while (bytesLeft > 0 && 126354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (bytesRead = read(fd, (void *)buf, bytesLeft)) > 0) { 127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesLeft -= bytesRead; 128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao buf += bytesRead; 129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (bytesRead <= 0) 131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return bytesRead; 132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return len; 133b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 134b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid Sync(ArgStruct * p) 136b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char s[] = "SyncMe"; 138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char response[7]; 139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (write(p->commfd, s, strlen(s)) < 0 || 141354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao readFully(p->commfd, response, strlen(s)) < 0) { 142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao perror 143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("NetPIPE: error writing or reading synchronization string"); 144354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(3); 145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (strncmp(s, response, strlen(s))) { 147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, "NetPIPE: Synchronization string incorrect!\n"); 148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(3); 149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 150b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 151b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid PrepareToReceive(ArgStruct * p) 153b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 154b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew /* 155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao The Berkeley sockets interface doesn't have a method to pre-post 156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao a buffer for reception of data. 157354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao */ 158b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 159b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid SendData(ArgStruct * p) 161b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesWritten, bytesLeft; 163354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *q; 164354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 165354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesLeft = p->bufflen; 166354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesWritten = 0; 167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao q = p->buff; 168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao while (bytesLeft > 0 && 169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (bytesWritten = write(p->commfd, q, bytesLeft)) > 0) { 170354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesLeft -= bytesWritten; 171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao q += bytesWritten; 172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (bytesWritten == -1) { 174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: write: error encountered, errno=%d\n", errno); 175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(401); 176354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 177b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 178b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid RecvData(ArgStruct * p) 180b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesLeft; 182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesRead; 183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *q; 184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesLeft = p->bufflen; 186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesRead = 0; 187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao q = p->buff1; 188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao while (bytesLeft > 0 && (bytesRead = read(p->commfd, q, bytesLeft)) > 0) { 189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesLeft -= bytesRead; 190354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao q += bytesRead; 191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 192354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (bytesLeft > 0 && bytesRead == 0) { 193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 194354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("NetPIPE: \"end of file\" encountered on reading from socket\n"); 195354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (bytesRead == -1) { 196354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: read: error encountered, errno=%d\n", errno); 197354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(401); 198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 199b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 200b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid SendTime(ArgStruct * p, double *t) 202b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned int ltime, ntime; 204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* 206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao Multiply the number of seconds by 1e6 to get time in microseconds 207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao and convert value to an unsigned 32-bit integer. 208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao */ 209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ltime = (unsigned int)(*t * 1.e6); 210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 211354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Send time in network order */ 212354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ntime = htonl(ltime); 213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (write(p->commfd, (char *)&ntime, sizeof(unsigned int)) < 0) { 214354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: write failed in SendTime: errno=%d\n", errno); 215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(301); 216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 217b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 218b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid RecvTime(ArgStruct * p, double *t) 220b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned int ltime, ntime; 222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesRead; 223354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 224354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(unsigned int)); 225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (bytesRead < 0) { 226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno); 227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(302); 228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (bytesRead != sizeof(unsigned int)) { 229354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 230354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "NetPIPE: partial read in RecvTime of %d bytes\n", 231354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesRead); 232354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(303); 233354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ltime = ntohl(ntime); 235354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Result is ltime (in microseconds) divided by 1.0e6 to get seconds */ 237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao *t = (double)ltime / 1.0e6; 238b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 239b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 240354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid SendRepeat(ArgStruct * p, int rpt) 241b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned int lrpt, nrpt; 243354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 244354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lrpt = rpt; 245354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Send repeat count as an unsigned 32 bit integer in network order */ 246354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao nrpt = htonl(lrpt); 247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (write(p->commfd, (void *)&nrpt, sizeof(unsigned int)) < 0) { 248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: write failed in SendRepeat: errno=%d\n", 249354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(304); 251354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 252b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 253b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid RecvRepeat(ArgStruct * p, int *rpt) 255b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 256354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unsigned int lrpt, nrpt; 257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int bytesRead; 258354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(unsigned int)); 260354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (bytesRead < 0) { 261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno); 262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(305); 263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else if (bytesRead != sizeof(unsigned int)) { 264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fprintf(stderr, 265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "NetPIPE: partial read in RecvRepeat of %d bytes\n", 266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao bytesRead); 267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(306); 268354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao lrpt = ntohl(nrpt); 270354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao *rpt = lrpt; 272b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 273b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint Establish(ArgStruct * p) 275b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao socklen_t clen; 277354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int one = 1; 278354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct protoent *proto; 279354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 280354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao clen = sizeof(p->prot.sin2); 281354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (p->tr) { 282354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (connect(p->commfd, (struct sockaddr *)&(p->prot.sin1), 283354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(p->prot.sin1)) < 0) { 284354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Client: Cannot Connect! errno=%d\n", errno); 285354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-10); 286354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 288354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* SERVER */ 289354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao listen(p->servicefd, 5); 290354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao p->commfd = 291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao accept(p->servicefd, (struct sockaddr *)&(p->prot.sin2), 292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &clen); 293354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 294354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (p->commfd < 0) { 295354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Server: Accept Failed! errno=%d\n", errno); 296354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(-12); 297354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 298354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 299354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* 300354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao Attempt to set TCP_NODELAY. TCP_NODELAY may or may not be propagated 301354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao to accepted sockets. 302354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao */ 303354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (!(proto = getprotobyname("tcp"))) { 304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("unknown protocol!\n"); 305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(555); 306354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 307354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 308354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (setsockopt(p->commfd, proto->p_proto, TCP_NODELAY, 309354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &one, sizeof(one)) < 0) { 310354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("setsockopt: TCP_NODELAY failed! errno=%d\n", 311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 312354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(556); 313354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* If requested, set the send and receive buffer sizes */ 316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (p->prot.sndbufsz > 0) { 317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 318354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("Send and Receive Buffers on accepted socket set to %d bytes\n", 319354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao p->prot.sndbufsz); 320354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (setsockopt 321354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (p->commfd, SOL_SOCKET, SO_SNDBUF, 322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &(p->prot.sndbufsz), 323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(p->prot.sndbufsz)) < 0) { 324354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 325354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("setsockopt: SO_SNDBUF failed! errno=%d\n", 326354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 327354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(556); 328354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 329354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (setsockopt 330354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao (p->commfd, SOL_SOCKET, SO_RCVBUF, 331354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao &(p->prot.rcvbufsz), 332354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sizeof(p->prot.rcvbufsz)) < 0) { 333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf 334354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ("setsockopt: SO_RCVBUF failed! errno=%d\n", 335354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao errno); 336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(556); 337354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 338354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 339354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 340354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return (0); 341b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew} 342b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew 343354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint CleanUp(ArgStruct * p) 344b1cd5fc471d12f7c4bda56c6da5d63287e42bfferobbiew{ 345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *quit = "QUIT"; 346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (p->tr) { 347354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao write(p->commfd, quit, 5); 348354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao read(p->commfd, quit, 5); 349354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p->commfd); 350354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } else { 351354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao read(p->commfd, quit, 5); 352354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao write(p->commfd, quit, 5); 353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p->commfd); 354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(p->servicefd); 355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 356354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return (0); 357ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 358