"Fossies" - the Fresh Open Source Software Archive

Member "NetPIPE-3.7.2/src/tcp.c" (19 Aug 2010, 11652 Bytes) of package /linux/privat/old/NetPIPE-3.7.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tcp.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.x_vs_3.7.2.

    1 /*****************************************************************************/
    2 /* "NetPIPE" -- Network Protocol Independent Performance Evaluator.          */
    3 /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc.      */
    4 /*                                                                           */
    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.   */
   10 /*                                                                           */
   11 /*     * tcp.c              ---- TCP calls source                            */
   12 /*     * tcp.h              ---- Include file for TCP calls and data structs */
   13 /*****************************************************************************/
   14 #include    "netpipe.h"
   15 
   16 #if defined (MPLITE)
   17 #include "mplite.h"
   18 #endif
   19 
   20 
   21 int doing_reset = 0;
   22 
   23 void Init(ArgStruct *p, int* pargc, char*** pargv)
   24 {
   25    p->reset_conn = 0; /* Default to not resetting connection */
   26    p->prot.sndbufsz = p->prot.rcvbufsz = 0;
   27    p->tr = 0;     /* The transmitter will be set using the -h host flag. */
   28    p->rcv = 1;
   29 }
   30 
   31 void Setup(ArgStruct *p)
   32 {
   33 
   34  int one = 1;
   35  int sockfd;
   36  struct sockaddr_in *lsin1, *lsin2;      /* ptr to sockaddr_in in ArgStruct */
   37  char *host;
   38  struct hostent *addr;
   39  struct protoent *proto;
   40  int send_size, recv_size, sizeofint = sizeof(int);
   41  int socket_family = AF_INET;
   42 
   43 
   44  host = p->host;                           /* copy ptr to hostname */ 
   45 
   46  if (p->use_sdp){
   47      printf("Using AF_INET_SDP (27) socket family\n");
   48      socket_family = 27;
   49  }
   50  
   51  lsin1 = &(p->prot.sin1);
   52  lsin2 = &(p->prot.sin2);
   53 
   54  bzero((char *) lsin1, sizeof(*lsin1));
   55  bzero((char *) lsin2, sizeof(*lsin2));
   56 
   57  if ( (sockfd = socket(socket_family, SOCK_STREAM, 0)) < 0){ 
   58    printf("NetPIPE: can't open stream socket! errno=%d\n", errno);
   59    exit(-4);
   60  }
   61 
   62  if(!(proto = getprotobyname("tcp"))){
   63    printf("NetPIPE: protocol 'tcp' unknown!\n");
   64    exit(555);
   65  }
   66 
   67     /* Attempt to set TCP_NODELAY */
   68 
   69  if(setsockopt(sockfd, proto->p_proto, TCP_NODELAY, &one, sizeof(one)) < 0)
   70  {
   71    printf("NetPIPE: setsockopt: TCP_NODELAY failed! errno=%d\n", errno);
   72    exit(556);
   73  }
   74 
   75    /* If requested, set the send and receive buffer sizes */
   76 
   77  if(p->prot.sndbufsz > 0)
   78  {
   79      if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 
   80                                        sizeof(p->prot.sndbufsz)) < 0)
   81      {
   82           printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
   83           printf("You may have asked for a buffer larger than the system can handle\n");
   84           exit(556);
   85      }
   86      if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
   87                                        sizeof(p->prot.rcvbufsz)) < 0)
   88      {
   89           printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
   90           printf("You may have asked for a buffer larger than the system can handle\n");
   91           exit(556);
   92      }
   93  }
   94  getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
   95                  (char *) &send_size, (void *) &sizeofint);
   96  getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
   97                  (char *) &recv_size, (void *) &sizeofint);
   98  
   99  if(!doing_reset) {
  100    fprintf(stderr,"Send and receive buffers are %d and %d bytes\n",
  101            send_size, recv_size);
  102    fprintf(stderr, "(A bug in Linux doubles the requested buffer sizes)\n");
  103  }
  104 
  105  if( p->tr ) {                             /* Primary transmitter */
  106 
  107    if (atoi(host) > 0) {                   /* Numerical IP address */
  108      lsin1->sin_family = AF_INET;
  109      lsin1->sin_addr.s_addr = inet_addr(host);
  110 
  111    } else {
  112       
  113      if ((addr = gethostbyname(host)) == NULL){
  114        printf("NetPIPE: invalid hostname '%s'\n", host);
  115        exit(-5);
  116      }
  117 
  118      lsin1->sin_family = addr->h_addrtype;
  119      bcopy(addr->h_addr, (char*) &(lsin1->sin_addr.s_addr), addr->h_length);
  120    }
  121 
  122    lsin1->sin_port = htons(p->port);
  123 
  124    p->commfd = sockfd;
  125 
  126  } else if( p->rcv ) {                     /* we are the receiver */
  127    
  128    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int))) {
  129      printf("NetPIPE: server: unable to setsockopt -- errno %d\n", errno);
  130      exit(557);
  131    }
  132 
  133    bzero((char *) lsin1, sizeof(*lsin1));
  134    lsin1->sin_family      = AF_INET;
  135    lsin1->sin_addr.s_addr = htonl(INADDR_ANY);
  136    lsin1->sin_port        = htons(p->port);
  137    
  138    if (bind(sockfd, (struct sockaddr *) lsin1, sizeof(*lsin1)) < 0){
  139      printf("NetPIPE: server: bind on local address failed! errno=%d\n", errno);
  140      exit(-6);
  141    }
  142 
  143    p->servicefd = sockfd;
  144  }
  145  p->upper = send_size + recv_size;
  146 
  147  establish(p);                               /* Establish connections */
  148 
  149 }   
  150 
  151 static int
  152 readFully(int fd, void *obuf, int len)
  153 {
  154   int bytesLeft = len;
  155   char *buf = (char *) obuf;
  156   int bytesRead = 0;
  157 
  158   while (bytesLeft > 0 &&
  159          (bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
  160     {
  161       bytesLeft -= bytesRead;
  162       buf += bytesRead;
  163     }
  164   if (bytesRead <= 0) return bytesRead;
  165   return len;
  166 }
  167 
  168 void Sync(ArgStruct *p)
  169 {
  170     char s[] = "SyncMe", response[] = "      ";
  171 
  172     if (write(p->commfd, s, strlen(s)) < 0 ||           /* Write to nbor */
  173         readFully(p->commfd, response, strlen(s)) < 0)  /* Read from nbor */
  174       {
  175         perror("NetPIPE: error writing or reading synchronization string");
  176         exit(3);
  177       }
  178     if (strncmp(s, response, strlen(s)))
  179       {
  180         fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", response);
  181         exit(3);
  182       }
  183 }
  184 
  185 void PrepareToReceive(ArgStruct *p)
  186 {
  187         /*
  188             The Berkeley sockets interface doesn't have a method to pre-post
  189             a buffer for reception of data.
  190         */
  191 }
  192 
  193 void SendData(ArgStruct *p)
  194 {
  195     int bytesWritten, bytesLeft;
  196     char *q;
  197 
  198     bytesLeft = p->bufflen;
  199     bytesWritten = 0;
  200     q = p->s_ptr;
  201     while (bytesLeft > 0 &&
  202            (bytesWritten = write(p->commfd, q, bytesLeft)) > 0)
  203       {
  204         bytesLeft -= bytesWritten;
  205         q += bytesWritten;
  206       }
  207     if (bytesWritten == -1)
  208       {
  209         printf("NetPIPE: write: error encountered, errno=%d\n", errno);
  210         exit(401);
  211       }
  212 }
  213 
  214 void RecvData(ArgStruct *p)
  215 {
  216     int bytesLeft;
  217     int bytesRead;
  218     char *q;
  219 
  220     bytesLeft = p->bufflen;
  221     bytesRead = 0;
  222     q = p->r_ptr;
  223     while (bytesLeft > 0 &&
  224            (bytesRead = read(p->commfd, q, bytesLeft)) > 0)
  225       {
  226         bytesLeft -= bytesRead;
  227         q += bytesRead;
  228       }
  229     if (bytesLeft > 0 && bytesRead == 0)
  230       {
  231         printf("NetPIPE: \"end of file\" encountered on reading from socket\n");
  232       }
  233     else if (bytesRead == -1)
  234       {
  235         printf("NetPIPE: read: error encountered, errno=%d\n", errno);
  236         exit(401);
  237       }
  238 }
  239 
  240 /* uint32_t is used to insure that the integer size is the same even in tests 
  241  * between 64-bit and 32-bit architectures. */
  242 
  243 void SendTime(ArgStruct *p, double *t)
  244 {
  245     uint32_t ltime, ntime;
  246 
  247     /*
  248       Multiply the number of seconds by 1e8 to get time in 0.01 microseconds
  249       and convert value to an unsigned 32-bit integer.
  250       */
  251     ltime = (uint32_t)(*t * 1.e8);
  252 
  253     /* Send time in network order */
  254     ntime = htonl(ltime);
  255     if (write(p->commfd, (char *)&ntime, sizeof(uint32_t)) < 0)
  256       {
  257         printf("NetPIPE: write failed in SendTime: errno=%d\n", errno);
  258         exit(301);
  259       }
  260 }
  261 
  262 void RecvTime(ArgStruct *p, double *t)
  263 {
  264     uint32_t ltime, ntime;
  265     int bytesRead;
  266 
  267     bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(uint32_t));
  268     if (bytesRead < 0)
  269       {
  270         printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno);
  271         exit(302);
  272       }
  273     else if (bytesRead != sizeof(uint32_t))
  274       {
  275         fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n",
  276                 bytesRead);
  277         exit(303);
  278       }
  279     ltime = ntohl(ntime);
  280 
  281         /* Result is ltime (in microseconds) divided by 1.0e8 to get seconds */
  282 
  283     *t = (double)ltime / 1.0e8;
  284 }
  285 
  286 void SendRepeat(ArgStruct *p, int rpt)
  287 {
  288   uint32_t lrpt, nrpt;
  289 
  290   lrpt = rpt;
  291   /* Send repeat count as a long in network order */
  292   nrpt = htonl(lrpt);
  293   if (write(p->commfd, (void *) &nrpt, sizeof(uint32_t)) < 0)
  294     {
  295       printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno);
  296       exit(304);
  297     }
  298 }
  299 
  300 void RecvRepeat(ArgStruct *p, int *rpt)
  301 {
  302   uint32_t lrpt, nrpt;
  303   int bytesRead;
  304 
  305   bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(uint32_t));
  306   if (bytesRead < 0)
  307     {
  308       printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno);
  309       exit(305);
  310     }
  311   else if (bytesRead != sizeof(uint32_t))
  312     {
  313       fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n",
  314               bytesRead);
  315       exit(306);
  316     }
  317   lrpt = ntohl(nrpt);
  318 
  319   *rpt = lrpt;
  320 }
  321 
  322 void establish(ArgStruct *p)
  323 {
  324   int one = 1;
  325   socklen_t clen;
  326   struct protoent *proto;
  327 
  328   clen = (socklen_t) sizeof(p->prot.sin2);
  329 
  330   if( p->tr ){
  331 
  332     while( connect(p->commfd, (struct sockaddr *) &(p->prot.sin1),
  333                    sizeof(p->prot.sin1)) < 0 ) {
  334 
  335       /* If we are doing a reset and we get a connection refused from
  336        * the connect() call, assume that the other node has not yet
  337        * gotten to its corresponding accept() call and keep trying until
  338        * we have success.
  339        */
  340       if(!doing_reset || errno != ECONNREFUSED) {
  341         printf("Client: Cannot Connect! errno=%d\n",errno);
  342         exit(-10);
  343       } 
  344         
  345     }
  346 
  347   } else if( p->rcv ) {
  348 
  349     /* SERVER */
  350     listen(p->servicefd, 5);
  351     p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sin2), &clen);
  352 
  353     if(p->commfd < 0){
  354       printf("Server: Accept Failed! errno=%d\n",errno);
  355       exit(-12);
  356     }
  357 
  358     /*
  359       Attempt to set TCP_NODELAY. TCP_NODELAY may or may not be propagated
  360       to accepted sockets.
  361      */
  362     if(!(proto = getprotobyname("tcp"))){
  363       printf("unknown protocol!\n");
  364       exit(555);
  365     }
  366 
  367     if(setsockopt(p->commfd, proto->p_proto, TCP_NODELAY,
  368                   &one, sizeof(one)) < 0)
  369     {
  370       printf("setsockopt: TCP_NODELAY failed! errno=%d\n", errno);
  371       exit(556);
  372     }
  373     
  374     /* If requested, set the send and receive buffer sizes */
  375     if(p->prot.sndbufsz > 0)
  376     {
  377 /*      printf("Send and Receive Buffers on accepted socket set to %d bytes\n",*/
  378 /*           p->prot.sndbufsz);*/
  379       if(setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 
  380                                        sizeof(p->prot.sndbufsz)) < 0)
  381       {
  382         printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
  383         exit(556);
  384       }
  385       if(setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
  386                                        sizeof(p->prot.rcvbufsz)) < 0)
  387       {
  388         printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
  389         exit(556);
  390       }
  391     }
  392   }
  393 }
  394 
  395 void CleanUp(ArgStruct *p)
  396 {
  397    char quit[] = "QUIT";
  398 
  399    if (p->tr) {
  400 
  401       write(p->commfd,quit, 5);
  402       read(p->commfd, quit, 5);
  403       close(p->commfd);
  404 
  405    } else if( p->rcv ) {
  406 
  407       read(p->commfd,quit, 5);
  408       write(p->commfd,quit,5);
  409       close(p->commfd);
  410       close(p->servicefd);
  411 
  412    }
  413 }
  414 
  415 
  416 void Reset(ArgStruct *p)
  417 {
  418   
  419   /* Reset sockets */
  420 
  421   if(p->reset_conn) {
  422 
  423     doing_reset = 1;
  424 
  425     /* Close the sockets */
  426 
  427     CleanUp(p);
  428 
  429     /* Now open and connect new sockets */
  430 
  431     Setup(p);
  432 
  433   }
  434 
  435 }
  436 
  437 void AfterAlignmentInit(ArgStruct *p)
  438 {
  439 
  440 }
  441