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
/* * sctp.c ---- SCTP calls source */
12
/*****************************************************************************/
22
void Init(ArgStruct *p, int* pargc, char*** pargv)
24
p->reset_conn = 0; /* Default to not resetting connection */
25
p->prot.sndbufsz = p->prot.rcvbufsz = 0;
26
p->tr = 0; /* The transmitter will be set using the -h host flag. */
30
void Setup(ArgStruct *p)
35
struct sockaddr_in *lsin1, *lsin2; /* ptr to sockaddr_in in ArgStruct */
38
struct protoent *proto;
39
int send_size, recv_size, sizeofint = sizeof(int);
42
host = p->host; /* copy ptr to hostname */
44
lsin1 = &(p->prot.sin1);
45
lsin2 = &(p->prot.sin2);
47
bzero((char *) lsin1, sizeof(*lsin1));
48
bzero((char *) lsin2, sizeof(*lsin2));
50
if ( (sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0){
51
printf("NetPIPE: can't open stream socket! errno=%d\n", errno);
55
if(!(proto = getprotobyname("sctp"))){
56
printf("NetPIPE: protocol 'sctp' unknown!\n");
60
/* Attempt to set SCTP_NODELAY */
62
if(setsockopt(sockfd, proto->p_proto, SCTP_NODELAY, &one, sizeof(one)) < 0)
64
printf("NetPIPE: setsockopt: SCTP_NODELAY failed! errno=%d\n", errno);
68
/* If requested, set the send and receive buffer sizes */
70
if(p->prot.sndbufsz > 0)
72
if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz),
73
sizeof(p->prot.sndbufsz)) < 0)
75
printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
76
printf("You may have asked for a buffer larger than the system can handle\n");
79
if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz),
80
sizeof(p->prot.rcvbufsz)) < 0)
82
printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
83
printf("You may have asked for a buffer larger than the system can handle\n");
87
getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
88
(char *) &send_size, (void *) &sizeofint);
89
getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
90
(char *) &recv_size, (void *) &sizeofint);
93
fprintf(stderr,"Send and receive buffers are %d and %d bytes\n",
94
send_size, recv_size);
95
fprintf(stderr, "(A bug in Linux doubles the requested buffer sizes)\n");
98
if( p->tr ) { /* Primary transmitter */
100
if (atoi(host) > 0) { /* Numerical IP address */
101
lsin1->sin_family = AF_INET;
102
lsin1->sin_addr.s_addr = inet_addr(host);
106
if ((addr = gethostbyname(host)) == NULL){
107
printf("NetPIPE: invalid hostname '%s'\n", host);
111
lsin1->sin_family = addr->h_addrtype;
112
bcopy(addr->h_addr, (char*) &(lsin1->sin_addr.s_addr), addr->h_length);
115
lsin1->sin_port = htons(p->port);
119
} else if( p->rcv ) { /* we are the receiver */
121
bzero((char *) lsin1, sizeof(*lsin1));
122
lsin1->sin_family = AF_INET;
123
lsin1->sin_addr.s_addr = htonl(INADDR_ANY);
124
lsin1->sin_port = htons(p->port);
126
if (bind(sockfd, (struct sockaddr *) lsin1, sizeof(*lsin1)) < 0){
127
printf("NetPIPE: server: bind on local address failed! errno=%d", errno);
131
p->servicefd = sockfd;
133
p->upper = send_size + recv_size;
135
establish(p); /* Establish connections */
140
readFully(int fd, void *obuf, int len)
143
char *buf = (char *) obuf;
146
while (bytesLeft > 0 &&
147
(bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
149
bytesLeft -= bytesRead;
152
if (bytesRead <= 0) return bytesRead;
156
void Sync(ArgStruct *p)
158
char s[] = "SyncMe", response[] = " ";
160
if (write(p->commfd, s, strlen(s)) < 0 || /* Write to nbor */
161
readFully(p->commfd, response, strlen(s)) < 0) /* Read from nbor */
163
perror("NetPIPE: error writing or reading synchronization string");
166
if (strncmp(s, response, strlen(s)))
168
fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", response);
173
void PrepareToReceive(ArgStruct *p)
176
The Berkeley sockets interface doesn't have a method to pre-post
177
a buffer for reception of data.
181
void SendData(ArgStruct *p)
183
int bytesWritten, bytesLeft;
186
bytesLeft = p->bufflen;
189
while (bytesLeft > 0 &&
190
(bytesWritten = write(p->commfd, q, bytesLeft)) > 0)
192
bytesLeft -= bytesWritten;
195
if (bytesWritten == -1)
197
printf("NetPIPE: write: error encountered, errno=%d\n", errno);
202
void RecvData(ArgStruct *p)
208
bytesLeft = p->bufflen;
211
while (bytesLeft > 0 &&
212
(bytesRead = read(p->commfd, q, bytesLeft)) > 0)
214
bytesLeft -= bytesRead;
217
if (bytesLeft > 0 && bytesRead == 0)
219
printf("NetPIPE: \"end of file\" encountered on reading from socket\n");
221
else if (bytesRead == -1)
223
printf("NetPIPE: read: error encountered, errno=%d\n", errno);
228
/* uint32_t is used to insure that the integer size is the same even in tests
229
* between 64-bit and 32-bit architectures. */
231
void SendTime(ArgStruct *p, double *t)
233
uint32_t ltime, ntime;
236
Multiply the number of seconds by 1e8 to get time in 0.01 microseconds
237
and convert value to an unsigned 32-bit integer.
239
ltime = (uint32_t)(*t * 1.e8);
241
/* Send time in network order */
242
ntime = htonl(ltime);
243
if (write(p->commfd, (char *)&ntime, sizeof(uint32_t)) < 0)
245
printf("NetPIPE: write failed in SendTime: errno=%d\n", errno);
250
void RecvTime(ArgStruct *p, double *t)
252
uint32_t ltime, ntime;
255
bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(uint32_t));
258
printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno);
261
else if (bytesRead != sizeof(uint32_t))
263
fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n",
267
ltime = ntohl(ntime);
269
/* Result is ltime (in microseconds) divided by 1.0e8 to get seconds */
271
*t = (double)ltime / 1.0e8;
274
void SendRepeat(ArgStruct *p, int rpt)
279
/* Send repeat count as a long in network order */
281
if (write(p->commfd, (void *) &nrpt, sizeof(uint32_t)) < 0)
283
printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno);
288
void RecvRepeat(ArgStruct *p, int *rpt)
293
bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(uint32_t));
296
printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno);
299
else if (bytesRead != sizeof(uint32_t))
301
fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n",
310
void establish(ArgStruct *p)
314
struct protoent *proto;
316
clen = (socklen_t) sizeof(p->prot.sin2);
320
while( connect(p->commfd, (struct sockaddr *) &(p->prot.sin1),
321
sizeof(p->prot.sin1)) < 0 ) {
323
/* If we are doing a reset and we get a connection refused from
324
* the connect() call, assume that the other node has not yet
325
* gotten to its corresponding accept() call and keep trying until
328
if(!doing_reset || errno != ECONNREFUSED) {
329
printf("Client: Cannot Connect! errno=%d\n",errno);
335
} else if( p->rcv ) {
338
listen(p->servicefd, 5);
339
p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sin2), &clen);
342
printf("Server: Accept Failed! errno=%d\n",errno);
347
Attempt to set SCTP_NODELAY. SCTP_NODELAY may or may not be propagated
350
if(!(proto = getprotobyname("sctp"))){
351
printf("unknown protocol!\n");
355
if(setsockopt(p->commfd, proto->p_proto, SCTP_NODELAY,
356
&one, sizeof(one)) < 0)
358
printf("setsockopt: SCTP_NODELAY failed! errno=%d\n", errno);
362
/* If requested, set the send and receive buffer sizes */
363
if(p->prot.sndbufsz > 0)
365
/* printf("Send and Receive Buffers on accepted socket set to %d bytes\n",*/
366
/* p->prot.sndbufsz);*/
367
if(setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz),
368
sizeof(p->prot.sndbufsz)) < 0)
370
printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
373
if(setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz),
374
sizeof(p->prot.rcvbufsz)) < 0)
376
printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
383
void CleanUp(ArgStruct *p)
389
write(p->commfd,quit, 5);
390
read(p->commfd, quit, 5);
393
} else if( p->rcv ) {
395
read(p->commfd,quit, 5);
396
write(p->commfd,quit,5);
404
void Reset(ArgStruct *p)
413
/* Close the sockets */
417
/* Now open and connect new sockets */
425
void AfterAlignmentInit(ArgStruct *p)