1
/*****************************************************************************/
2
/* "NetPIPE" -- Network Protocol Independent Performance Evaluator. */
3
/* Copyright 1997, 1998 Iowa State University Research Foundation, Inc. */
5
/* This program is free software; you can redistribute it and/or modify */
6
/* it under the terms of the GNU General Public License as published by */
7
/* the Free Software Foundation. You should have received a copy of the */
8
/* GNU General Public License along with this program; if not, write to the */
9
/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
11
/* TCP6 extension Copyright 2004 George V. Neville-Neil and Neville-Neil */
14
/* * tcp6.c ---- TCP over IPv6 calls source */
15
/* * tcp.h ---- Include file for TCP6 calls and data structs */
16
/*****************************************************************************/
26
void Init(ArgStruct *p, int* pargc, char*** pargv)
28
p->reset_conn = 0; /* Default to not resetting connection */
29
p->prot.sndbufsz = p->prot.rcvbufsz = 0;
30
/* The transmitter will be set using the -h host flag. */
35
void Setup(ArgStruct *p)
39
/* ptr to sockaddr_in in ArgStruct */
40
struct sockaddr_in6 *lsin1, *lsin2;
44
struct protoent *proto;
45
int send_size, recv_size, sizeofint = sizeof(int);
47
host = p->host; /* copy ptr to hostname */
49
lsin1 = &(p->prot.sin1);
50
lsin2 = &(p->prot.sin2);
52
bzero((char *) lsin1, sizeof(*lsin1));
53
bzero((char *) lsin2, sizeof(*lsin2));
55
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0){
56
printf("NetPIPE: can't open stream socket! errno=%d\n", errno);
60
if(!(proto = getprotobyname("tcp"))){
61
printf("NetPIPE: protocol 'tcp' unknown!\n");
65
/* Attempt to set TCP_NODELAY */
67
if(setsockopt(sockfd, proto->p_proto, TCP_NODELAY, &one, sizeof(one)) < 0)
69
printf("NetPIPE: setsockopt: TCP_NODELAY failed! errno=%d\n", errno);
73
/* If requested, set the send and receive buffer sizes */
75
if(p->prot.sndbufsz > 0)
77
if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz),
78
sizeof(p->prot.sndbufsz)) < 0)
80
printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
81
printf("You may have asked for a buffer larger than the system can handle\n");
84
if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz),
85
sizeof(p->prot.rcvbufsz)) < 0)
87
printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
88
printf("You may have asked for a buffer larger than the system can handle\n");
92
getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
93
(char *) &send_size, (void *) &sizeofint);
94
getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
95
(char *) &recv_size, (void *) &sizeofint);
98
fprintf(stderr,"Send and receive buffers are %d and %d bytes\n",
99
send_size, recv_size);
100
fprintf(stderr, "(A bug in Linux doubles the requested buffer sizes)\n");
103
if( p->tr ) { /* Primary transmitter */
105
lsin1->sin6_family = AF_INET6;
107
/* First attempt to convert the string to an IPv6 */
109
/* If the user supplied a real host name this will fail and */
110
/* we'll then do a name lookup. */
112
if (inet_pton(AF_INET6, host, &lsin1->sin6_addr) == 0)
114
if ((hp = gethostbyname2(host, AF_INET6)) == NULL)
116
printf("NetPIPE: invalid hostname '%s'\n", host);
120
if (hp->h_addrtype != AF_INET6)
122
printf("NetPIPE: invalid hostname '%s'\n", host);
125
bcopy(hp->h_addr, (char*) &(lsin1->sin6_addr),
129
lsin1->sin6_port = htons(p->port);
133
} else if( p->rcv ) { /* we are the receiver */
134
bzero((char *) lsin1, sizeof(*lsin1));
135
lsin1->sin6_family = AF_INET6;
136
lsin1->sin6_len = sizeof(*lsin1);
137
lsin1->sin6_port = htons(p->port);
138
/* Setting this to all 0 is the "ANY" address. */
139
bzero(&lsin1->sin6_addr, sizeof(lsin1->sin6_addr));
141
if (bind(sockfd, (struct sockaddr *) lsin1, sizeof(*lsin1)) < 0){
142
printf("NetPIPE: server: bind on local address failed! errno=%d", errno);
146
p->servicefd = sockfd;
148
p->upper = send_size + recv_size;
150
establish(p); /* Establish connections */
155
readFully(int fd, void *obuf, int len)
158
char *buf = (char *) obuf;
161
while (bytesLeft > 0 &&
162
(bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
164
bytesLeft -= bytesRead;
167
if (bytesRead <= 0) return bytesRead;
171
void Sync(ArgStruct *p)
173
char s[] = "SyncMe", response[] = " ";
175
if (write(p->commfd, s, strlen(s)) < 0 || /* Write to nbor */
176
readFully(p->commfd, response, strlen(s)) < 0) /* Read from nbor */
178
perror("NetPIPE: error writing or reading synchronization string");
181
if (strncmp(s, response, strlen(s)))
183
fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", response);
188
void PrepareToReceive(ArgStruct *p)
191
The Berkeley sockets interface doesn't have a method to pre-post
192
a buffer for reception of data.
196
void SendData(ArgStruct *p)
198
int bytesWritten, bytesLeft;
201
bytesLeft = p->bufflen;
204
while (bytesLeft > 0 &&
205
(bytesWritten = write(p->commfd, q, bytesLeft)) > 0)
207
bytesLeft -= bytesWritten;
210
if (bytesWritten == -1)
212
printf("NetPIPE: write: error encountered, errno=%d\n", errno);
217
void RecvData(ArgStruct *p)
223
bytesLeft = p->bufflen;
226
while (bytesLeft > 0 &&
227
(bytesRead = read(p->commfd, q, bytesLeft)) > 0)
229
bytesLeft -= bytesRead;
232
if (bytesLeft > 0 && bytesRead == 0)
234
printf("NetPIPE: \"end of file\" encountered on reading from socket\n");
236
else if (bytesRead == -1)
238
printf("NetPIPE: read: error encountered, errno=%d\n", errno);
243
/* uint32_t is used to insure that the integer size is the same even in tests
244
* between 64-bit and 32-bit architectures. */
246
void SendTime(ArgStruct *p, double *t)
248
uint32_t ltime, ntime;
251
Multiply the number of seconds by 1e8 to get time in 0.01 microseconds
252
and convert value to an unsigned 32-bit integer.
254
ltime = (uint32_t)(*t * 1.e8);
256
/* Send time in network order */
257
ntime = htonl(ltime);
258
if (write(p->commfd, (char *)&ntime, sizeof(uint32_t)) < 0)
260
printf("NetPIPE: write failed in SendTime: errno=%d\n", errno);
265
void RecvTime(ArgStruct *p, double *t)
267
uint32_t ltime, ntime;
270
bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(uint32_t));
273
printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno);
276
else if (bytesRead != sizeof(uint32_t))
278
fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n",
282
ltime = ntohl(ntime);
284
/* Result is ltime (in microseconds) divided by 1.0e8 to get seconds */
286
*t = (double)ltime / 1.0e8;
289
void SendRepeat(ArgStruct *p, int rpt)
294
/* Send repeat count as a long in network order */
296
if (write(p->commfd, (void *) &nrpt, sizeof(uint32_t)) < 0)
298
printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno);
303
void RecvRepeat(ArgStruct *p, int *rpt)
308
bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(uint32_t));
311
printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno);
314
else if (bytesRead != sizeof(uint32_t))
316
fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n",
325
void establish(ArgStruct *p)
329
struct protoent *proto;
331
clen = (socklen_t) sizeof(p->prot.sin2);
335
while( connect(p->commfd, (struct sockaddr *) &(p->prot.sin1),
336
sizeof(p->prot.sin1)) < 0 ) {
338
/* If we are doing a reset and we get a connection refused from
339
* the connect() call, assume that the other node has not yet
340
* gotten to its corresponding accept() call and keep trying until
343
if(!doing_reset || errno != ECONNREFUSED) {
344
printf("Client: Cannot Connect! errno=%d\n",errno);
350
} else if( p->rcv ) {
353
listen(p->servicefd, 5);
354
p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sin2), &clen);
357
printf("Server: Accept Failed! errno=%d\n",errno);
362
Attempt to set TCP_NODELAY. TCP_NODELAY may or may not be propagated
365
if(!(proto = getprotobyname("tcp"))){
366
printf("unknown protocol!\n");
370
if(setsockopt(p->commfd, proto->p_proto, TCP_NODELAY,
371
&one, sizeof(one)) < 0)
373
printf("setsockopt: TCP_NODELAY failed! errno=%d\n", errno);
377
/* If requested, set the send and receive buffer sizes */
378
if(p->prot.sndbufsz > 0)
380
/* printf("Send and Receive Buffers on accepted socket set to %d bytes\n",*/
381
/* p->prot.sndbufsz);*/
382
if(setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz),
383
sizeof(p->prot.sndbufsz)) < 0)
385
printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
388
if(setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz),
389
sizeof(p->prot.rcvbufsz)) < 0)
391
printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
398
void CleanUp(ArgStruct *p)
404
write(p->commfd,quit, 5);
405
read(p->commfd, quit, 5);
408
} else if( p->rcv ) {
410
read(p->commfd,quit, 5);
411
write(p->commfd,quit,5);
419
void Reset(ArgStruct *p)
428
/* Close the sockets */
432
/* Now open and connect new sockets */
440
void AfterAlignmentInit(ArgStruct *p)