/*************************************************************************** * DBS: Distributed Benchmark System * Copyright (c) 1995, 1996, 1997 Yukio Murayama * Copyright (c) 1995, 1996, 1997 Nara Institute of Science and Technology * All rights reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided only with the following * conditions are satisfied: * * 1. Both the copyright notice and this permission notice appear in * all copies of the software, derivative works or modified versions, * and any portions thereof, and that both notices appear in * supporting documentation. * 2. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * This product includes software developed by Nara Institute of * Science and Technology and its contributors. * 3. Neither the name of Nara Institute of Science and Technology nor * the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND NARA * INSTITUTE OF SCIENCE AND TECHNOLOGY DISCLAIMS ANY LIABILITY OF * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF * THIS SOFTWARE. ALSO, THERE IS NO WARRANTY IMPLIED OR OTHERWISE, * NOR IS SUPPORT PROVIDED. * * Feedback of the results generated from any improvements or * extensions made to this software would be much appreciated. * Any such feedback should be sent to: * * Yukio Murayama * E-mail: * URL: * Address: Graduate School of Information Science, * Nara Institute of Science and Technology, * Takayama 8916-5, Ikoma, Nara, Japan * * Nara Institute of Science and Technology has the rights to * redistribute these changes. ***************************************************************************/ /***************************************************************** * Distributed Benchmark System * Network Subroutines * $Revision: 1.18 $ * $Date: 1997/07/11 00:54:07 $ * $Author: yukio-m $ *****************************************************************/ #ifdef __linux__ #include #else #if !defined(sun) && !defined(mips) && !defined(ultrix) && !defined(__hpux) #include #endif #endif /*#define _SOCKADDR_LEN*/ #include #include #include #include #include #include #include #include #include #include #include #include #include "dbs.h" #include "dbsd.h" #define ASSOSIATION_DEBUG {\ int sp, dp, sa, da;\ sa=(int)ntohl(a->source_address);\ sp=(int)ntohs(a->source_port);\ da=(int)ntohl(a->dest_address);\ dp=(int)ntohs(a->dest_port);\ fprintf(stderr,"ASSOSIATION:(%3d.%3d.%3d.%3d, %3d.%3d.%3d.%3d)(%5d,%5d)\n",\ GET_IP_ADDR(sa,4), GET_IP_ADDR(sa,3), GET_IP_ADDR(sa,2), GET_IP_ADDR(sa,1),\ GET_IP_ADDR(da,4), GET_IP_ADDR(da,3), GET_IP_ADDR(da,2), GET_IP_ADDR(da,1),\ sp,dp);\ } void getaddr_sub __P((char *hostname, int port, struct sockaddr_in *address)); void socket_opt __P((int fd, struct dbsd_param *cmd)); /**************************************************************** * Address resolution Subroutine ****************************************************************/ /* * Get Address Subroutine * * {hostname, port} -> (struct sockaddr_in *)address */ void getaddr_sub(hostname, port, address) char *hostname; int port; struct sockaddr_in *address; { unsigned int tmp; struct hostent *hp; #ifndef INADDR_NONE #define INADDR_NONE (-1) #endif address->sin_family = AF_INET; address->sin_port = htons((short)port); if (strcmp(hostname,"") == 0) { address->sin_addr.s_addr = htonl(INADDR_ANY); } else { tmp = inet_addr(hostname); if(tmp != (unsigned long) INADDR_NONE){ address->sin_addr.s_addr = tmp; } else { if ((hp = gethostbyname(hostname)) == NULL) { char tmp[512]; sprintf(tmp, "gethostbyname \"%s\"", hostname); DEBUGMSG2(1, perror("gethostbyname")); safe_exit(GETHOSTBYNAME, tmp, strerror(errno)); } bcopy((char *)hp->h_addr, (char *)&address->sin_addr, hp->h_length); } } } /* * Get Address Subroutine * * Set (struct sockaddr_in *)address */ void getaddr(a, d_address, b_address) struct assosiation *a; struct sockaddr_in *d_address; struct sockaddr_in *b_address; { bzero((char *)d_address, sizeof(*d_address)); bzero((char *)b_address, sizeof(*b_address)); getaddr_sub(a->dsthostname, (int)a->dest_port, d_address); getaddr_sub(a->srchostname, (int)a->source_port, b_address); } /* * Set Address * * File Descripter -> (struct assosiation *) */ void setaddr(fd, a) int fd; struct assosiation *a; { struct sockaddr_in dest; struct sockaddr_in source; int len; len = sizeof (dest); getpeername(fd, (struct sockaddr *) &dest, &len); len = sizeof (source); getsockname(fd, (struct sockaddr *) &source, &len); a->source_address = source.sin_addr.s_addr; a->source_port = source.sin_port; a->dest_address = dest.sin_addr.s_addr; a->dest_port = dest.sin_port; DEBUGMSG2(5, ASSOSIATION_DEBUG); } /***************************************************************** * TCP Initialization Server * * Return Value: file descripter *****************************************************************/ int tcp_init_server(a, cmd) struct assosiation *a; struct dbsd_param *cmd; { getaddr(a, &cmd->d_address, &cmd->b_address); if ((cmd->sockfd = socket(cmd->d_address.sin_family, SOCK_STREAM, 0)) <0) safe_exit(SOCKET, "TCP SERVER socket", strerror(errno)); if (bind(cmd->sockfd, (struct sockaddr *)&cmd->b_address, sizeof(cmd->b_address)) < 0) safe_exit(BIND, "TCP SERVER bind", strerror(errno)); socket_opt(cmd->sockfd, cmd); listen(cmd->sockfd, 1); return 0; } /* * TCP Initialization Server2 * * Connection_mode == BEFORE */ int tcp_init_server2(a, cmd) struct assosiation *a; struct dbsd_param *cmd; { if (cmd->connection_mode == BEFORE) { int d_len = sizeof(cmd->d_address); DEBUGMSG2(2, fprintf(stderr, "Wait Connection from (%s).(%d).....", a->dsthostname, (int)ntohs(cmd->d_address.sin_port))); if ((cmd->fd = accept(cmd->sockfd, (struct sockaddr *)&cmd->d_address, &d_len)) < 0) safe_exit(ACCEPT, "TCP SERVER accept", strerror(errno)); DEBUGMSG(2, "Accepted.\n"); setaddr(cmd->fd, a); close(cmd->sockfd); return cmd->fd; } return 0; } /***************************************************************** * TCP Initialization Client * * Return Value: file descripter *****************************************************************/ int tcp_init_client(a, cmd) struct assosiation *a; struct dbsd_param *cmd; { DEBUGMSG(2, "TCP_INIT_CLIENT: "); getaddr(a, &cmd->d_address, &cmd->b_address); if ((cmd->fd = socket(cmd->d_address.sin_family, SOCK_STREAM, 0)) <0) safe_exit(SOCKET, "TCP CLIENT socket", strerror(errno)); if (bind(cmd->fd, (struct sockaddr *)&cmd->b_address, sizeof(cmd->b_address)) < 0) safe_exit(BIND, "TCP CLIENT bind", strerror(errno)); socket_opt(cmd->fd, cmd); if (cmd->connection_mode == BEFORE) { DEBUGMSG2(2, fprintf(stderr, "Connecting to (%s).(%u).....", a->dsthostname, (int)ntohs(cmd->d_address.sin_port))); if (connect(cmd->fd, (struct sockaddr *)&cmd->d_address, sizeof(cmd->d_address)) < 0) safe_exit(CONNECT, "TCP CLIENT connect", strerror(errno)); DEBUGMSG(2, "Connected.\n"); setaddr(cmd->fd, a); return cmd->fd; } return 0; } /***************************************************************** * UDP Initialization *****************************************************************/ int udp_init(a, cmd) struct assosiation *a; struct dbsd_param *cmd; { DEBUGMSG(2, "TCP_INIT_SERVER:\n"); getaddr(a, &cmd->d_address, &cmd->b_address); if ((cmd->fd = socket(cmd->d_address.sin_family, SOCK_DGRAM, 0)) < 0) safe_exit(SOCKET, "UDP Socket Open", strerror(errno)); if (bind(cmd->fd, (struct sockaddr *)&cmd->b_address, sizeof(cmd->b_address)) < 0) safe_exit(BIND, "UDP Bind Socket(Server)", strerror(errno)); socket_opt(cmd->fd, cmd); return cmd->fd; } /***************************************************************** * Set Socket Option *****************************************************************/ void socket_opt(fd, cmd) int fd; struct dbsd_param *cmd; { int i; i = cmd->sock_opt.send_buff; if (i > 0) { DEBUGMSG2(2, fprintf(stderr, " send_buff = %dbyte\n", i)); if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&i, sizeof(i)) < 0) safe_exit(SOSNDBUF, "setsockopt", strerror(errno)); } i = cmd->sock_opt.recv_buff; if (i > 0) { DEBUGMSG2(2, fprintf(stderr, " recv_buff = %dbyte\n", i)); if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&i, sizeof(i)) < 0) safe_exit(SORCVBUF, "setsockopt", strerror(errno)); } i = cmd->sock_opt.so_debug; if (i == ON) { DEBUGMSG2(2, fprintf(stderr, " so_debug = %s\n", (i==ON)?"ON":"OFF")); if (setsockopt(fd, SOL_SOCKET, SO_DEBUG, (char *)&i, sizeof(i)) < 0) safe_exit(SODEBUG, "setsockopt", strerror(errno)); } i = cmd->sock_opt.no_delay; if (i == ON) { DEBUGMSG2(2, fprintf(stderr, " tcp_nodelay = %s\n", (i==ON)?"ON":"OFF")); if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) safe_exit(TCPNODELAY, "setsockopt", strerror(errno)); } i = cmd->sock_opt.mss; if (i > 0) { DEBUGMSG2(2, fprintf(stderr, " mss = %dbyte\n", i)); if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (char *)&i, sizeof(i)) < 0) safe_exit(TCPMAXSEG, "setsockopt", strerror(errno)); } if (cmd->assosiation.transport == TCP) { int l = sizeof(i); if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (char *)&i, &l) < 0) safe_exit(ABNORMAL, "getsockopt", strerror(errno)); cmd->sock_opt.mss = i; l = sizeof(i); if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&i, &l) < 0) safe_exit(ABNORMAL, "getsockopt", strerror(errno)); cmd->sock_opt.send_buff = i; l = sizeof(i); if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&i, &l) < 0) safe_exit(ABNORMAL, "getsockopt", strerror(errno)); cmd->sock_opt.recv_buff = i; DEBUGMSG2(2, fprintf(stderr, " MSS=%d SNDBUF=%d RCVBUF=%d\n", cmd->sock_opt.mss, cmd->sock_opt.send_buff, cmd->sock_opt.recv_buff)); } }