"Fossies" - the Fresh Open Source Software Archive

Member "NetPIPE-3.7.2/src/tcp6.c" (19 Aug 2010, 11315 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 "tcp6.c" see the Fossies "Dox" file reference documentation.

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