"Fossies" - the Fresh Open Source Software Archive

Member "NetPIPE-3.7.2/src/sctp6.c" (19 Aug 2010, 11160 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 "sctp6.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 /*     * sctp6.c             ---- SCTP over IPv6 calls source                */
   12 /*****************************************************************************/
   13 #include    "netpipe.h"
   14 
   15 #if defined (MPLITE)
   16 #include "mplite.h"
   17 #endif
   18 
   19 
   20 int doing_reset = 0;
   21 
   22 void Init(ArgStruct *p, int* pargc, char*** pargv)
   23 {
   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. */
   27     p->rcv = 1;
   28 }
   29 
   30 void Setup(ArgStruct *p)
   31 {
   32     
   33     int one = 1;
   34     int sockfd;
   35     struct sockaddr_in6 *lsin1, *lsin2; /* ptr to sockaddr_in6 in ArgStruct */
   36     char *host;
   37     struct hostent *hp;
   38     struct protoent *proto;
   39     int send_size, recv_size, sizeofint = sizeof(int);
   40     
   41     
   42     host = p->host;                           /* copy ptr to hostname */ 
   43     
   44     lsin1 = &(p->prot.sin1);
   45     lsin2 = &(p->prot.sin2);
   46     
   47     bzero((char *) lsin1, sizeof(*lsin1));
   48     bzero((char *) lsin2, sizeof(*lsin2));
   49     
   50     if ( (sockfd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0){
   51     printf("NetPIPE: can't open stream socket! errno=%d\n", errno);
   52     exit(-4);
   53     }
   54     
   55     if(!(proto = getprotobyname("sctp"))){
   56     printf("NetPIPE: protocol 'sctp' unknown!\n");
   57     exit(555);
   58     }
   59     
   60     /* Attempt to set SCTP_NODELAY */
   61 
   62     if(setsockopt(sockfd, proto->p_proto, SCTP_NODELAY, &one, sizeof(one)) < 0)
   63     {
   64     printf("NetPIPE: setsockopt: SCTP_NODELAY failed! errno=%d\n", errno);
   65     exit(556);
   66     }
   67     
   68     /* If requested, set the send and receive buffer sizes */
   69     
   70     if(p->prot.sndbufsz > 0)
   71     {
   72     if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 
   73               sizeof(p->prot.sndbufsz)) < 0)
   74     {
   75         printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
   76         printf("You may have asked for a buffer larger than the system");
   77         printf("can handle\n");
   78 
   79         exit(556);
   80     }
   81     if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
   82               sizeof(p->prot.rcvbufsz)) < 0)
   83     {
   84         printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
   85         printf("You may have asked for a buffer larger than the system");
   86         printf("can handle\n");
   87         exit(556);
   88     }
   89     }
   90     getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
   91            (char *) &send_size, (void *) &sizeofint);
   92     getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
   93            (char *) &recv_size, (void *) &sizeofint);
   94     
   95     if(!doing_reset) {
   96     fprintf(stderr,"Send and receive buffers are %d and %d bytes\n",
   97         send_size, recv_size);
   98     fprintf(stderr,
   99         "(A bug in Linux doubles the requested buffer sizes)\n");
  100     }
  101     
  102     if( p->tr ) {                             /* Primary transmitter */
  103     
  104     lsin1->sin6_family = AF_INET6;
  105     
  106     /* First attempt to convert the string to an IPv6 */
  107     /* address. */
  108     /* If the user supplied a real host name this will fail and */
  109     /* we'll then do a name lookup. */
  110     
  111     if (inet_pton(AF_INET6, host, &lsin1->sin6_addr) == 0)
  112     {
  113         if ((hp = gethostbyname2(host, AF_INET6)) == NULL)
  114         {
  115         printf("NetPIPE: invalid hostname '%s'\n", host);
  116         exit(-5);
  117         }
  118         
  119         if (hp->h_addrtype != AF_INET6) 
  120         {
  121         printf("NetPIPE: invalid hostname '%s'\n", host);
  122         exit(-5);
  123         }
  124         bcopy(hp->h_addr, (char*) &(lsin1->sin6_addr), 
  125           hp->h_length);
  126     }
  127      
  128     lsin1->sin6_port = htons(p->port);
  129     
  130     p->commfd = sockfd;
  131     
  132     } else if( p->rcv ) {                     /* we are the receiver */
  133     
  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));
  140     
  141     if (bind(sockfd, (struct sockaddr *) lsin1, sizeof(*lsin1)) < 0){
  142         printf("NetPIPE: server: bind on local address failed! errno=%d", 
  143            errno);
  144         exit(-6);
  145     }
  146     
  147     p->servicefd = sockfd;
  148     }
  149     p->upper = send_size + recv_size;
  150     
  151     establish(p);                               /* Establish connections */
  152     
  153 }   
  154 
  155 static int
  156 readFully(int fd, void *obuf, int len)
  157 {
  158     int bytesLeft = len;
  159     char *buf = (char *) obuf;
  160     int bytesRead = 0;
  161 
  162     while (bytesLeft > 0 &&
  163        (bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
  164     {
  165     bytesLeft -= bytesRead;
  166     buf += bytesRead;
  167     }
  168     if (bytesRead <= 0) return bytesRead;
  169     return len;
  170 }
  171 
  172 void Sync(ArgStruct *p)
  173 {
  174     char s[] = "SyncMe", response[] = "      ";
  175 
  176     if (write(p->commfd, s, strlen(s)) < 0 ||           /* Write to nbor */
  177         readFully(p->commfd, response, strlen(s)) < 0)  /* Read from nbor */
  178     {
  179         perror("NetPIPE: error writing or reading synchronization string");
  180         exit(3);
  181     }
  182     if (strncmp(s, response, strlen(s)))
  183     {
  184         fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", 
  185         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 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), 
  357                &clen);
  358 
  359     if(p->commfd < 0){
  360         printf("Server: Accept Failed! errno=%d\n",errno);
  361         exit(-12);
  362     }
  363 
  364     /*
  365      * Attempt to set SCTP_NODELAY. SCTP_NODELAY may or may not be 
  366      * propagated to accepted sockets.
  367      */
  368     if(!(proto = getprotobyname("sctp"))){
  369         printf("unknown protocol!\n");
  370         exit(555);
  371     }
  372 
  373     if(setsockopt(p->commfd, proto->p_proto, SCTP_NODELAY,
  374               &one, sizeof(one)) < 0)
  375     {
  376         printf("setsockopt: SCTP_NODELAY failed! errno=%d\n", errno);
  377         exit(556);
  378     }
  379 
  380     /* If requested, set the send and receive buffer sizes */
  381     if(p->prot.sndbufsz > 0)
  382     {
  383         if(setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, 
  384               &(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, 
  391               &(p->prot.rcvbufsz), 
  392               sizeof(p->prot.rcvbufsz)) < 0)
  393         {
  394         printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
  395         exit(556);
  396         }
  397     }
  398     }
  399 }
  400 
  401 void CleanUp(ArgStruct *p)
  402 {
  403     char *quit="QUIT";
  404 
  405     if (p->tr) {
  406 
  407     write(p->commfd,quit, 5);
  408     read(p->commfd, quit, 5);
  409     close(p->commfd);
  410 
  411     } else if( p->rcv ) {
  412 
  413     read(p->commfd,quit, 5);
  414     write(p->commfd,quit,5);
  415     close(p->commfd);
  416     close(p->servicefd);
  417 
  418     }
  419 }
  420 
  421 
  422 void Reset(ArgStruct *p)
  423 {
  424   
  425     /* Reset sockets */
  426 
  427     if(p->reset_conn) {
  428 
  429     doing_reset = 1;
  430 
  431     /* Close the sockets */
  432 
  433     CleanUp(p);
  434 
  435     /* Now open and connect new sockets */
  436 
  437     Setup(p);
  438 
  439     }
  440 
  441 }
  442 
  443 void AfterAlignmentInit(ArgStruct *p)
  444 {
  445 
  446 }
  447