nsprpub/pr/tests/sockopt.c

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nspr.h"
     7 #include "prio.h"
     8 #include "prinit.h"
     9 #include "prprf.h"
    10 #include "obsolete/probslet.h"
    12 #include "plerror.h"
    14 #ifdef XP_UNIX
    15 #include <sys/socket.h>  /* SO_REUSEPORT */
    16 #endif
    18 static PRFileDesc *err = NULL;
    19 static PRBool failed = PR_FALSE;
    21 static void Failed(const char *msg1, const char *msg2)
    22 {
    23     if (NULL != msg1) PR_fprintf(err, "%s ", msg1);
    24     PL_FPrintError(err, msg2);
    25     failed = PR_TRUE;
    26 }  /* Failed */
    28 static PRSockOption Incr(PRSockOption *option)
    29 {
    30     PRIntn val = ((PRIntn)*option) + 1;
    31     *option = (PRSockOption)val;
    32     return (PRSockOption)val;
    33 }  /* Incr */
    35 int main(int argc, char **argv)
    36 {
    37     PRStatus rv;
    38     PRFileDesc *udp = PR_NewUDPSocket();
    39     PRFileDesc *tcp = PR_NewTCPSocket();
    40     const char *tag[] =
    41     {
    42         "PR_SockOpt_Nonblocking",     /* nonblocking io */
    43         "PR_SockOpt_Linger",          /* linger on close if data present */
    44         "PR_SockOpt_Reuseaddr",       /* allow local address reuse */
    45         "PR_SockOpt_Keepalive",       /* keep connections alive */
    46         "PR_SockOpt_RecvBufferSize",  /* send buffer size */
    47         "PR_SockOpt_SendBufferSize",  /* receive buffer size */
    49         "PR_SockOpt_IpTimeToLive",    /* time to live */
    50         "PR_SockOpt_IpTypeOfService", /* type of service and precedence */
    52         "PR_SockOpt_AddMember",       /* add an IP group membership */
    53         "PR_SockOpt_DropMember",      /* drop an IP group membership */
    54         "PR_SockOpt_McastInterface",  /* multicast interface address */
    55         "PR_SockOpt_McastTimeToLive", /* multicast timetolive */
    56         "PR_SockOpt_McastLoopback",   /* multicast loopback */
    58         "PR_SockOpt_NoDelay",         /* don't delay send to coalesce packets */
    59         "PR_SockOpt_MaxSegment",      /* maximum segment size */
    60         "PR_SockOpt_Broadcast",       /* Enable broadcast */
    61         "PR_SockOpt_Reuseport",       /* allow local address & port reuse */
    62         "PR_SockOpt_Last"
    63     };
    65     err = PR_GetSpecialFD(PR_StandardError);
    66     PR_STDIO_INIT();
    68     if (NULL == udp) Failed("PR_NewUDPSocket()", NULL);
    69     else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL);
    70     else
    71     {
    72         PRSockOption option;
    73         PRUint32 segment = 1024;
    74         PRNetAddr addr;
    76         rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr);
    77         if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL);
    78         rv = PR_Bind(udp, &addr);
    79         if (PR_FAILURE == rv) Failed("PR_Bind()", NULL);
    80         for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option))
    81         {
    82             PRSocketOptionData data;
    83             PRFileDesc *fd = tcp;
    84             data.option = option;
    85             switch (option)
    86             {
    87                 case PR_SockOpt_Nonblocking:
    88                     data.value.non_blocking = PR_TRUE;
    89                     break;    
    90 #ifndef SYMBIAN
    91                 case PR_SockOpt_Linger:
    92                     data.value.linger.polarity = PR_TRUE;
    93                     data.value.linger.linger = PR_SecondsToInterval(2);          
    94                     break;    
    95 #endif
    96                 case PR_SockOpt_Reuseaddr:
    97                     data.value.reuse_addr = PR_TRUE;      
    98                     break;    
    99                 case PR_SockOpt_Keepalive:       
   100                     data.value.keep_alive = PR_TRUE;      
   101                     break;    
   102                 case PR_SockOpt_RecvBufferSize:
   103                     data.value.recv_buffer_size = segment;  
   104                     break;    
   105                 case PR_SockOpt_SendBufferSize:  
   106                     data.value.send_buffer_size = segment;  
   107                     break;    
   108 #ifndef SYMBIAN
   109                 case PR_SockOpt_IpTimeToLive:
   110                     data.value.ip_ttl = 64;  
   111                     break;    
   112                 case PR_SockOpt_IpTypeOfService:
   113                     data.value.tos = 0; 
   114                     break;    
   115                 case PR_SockOpt_McastTimeToLive:
   116                     fd = udp; 
   117                     data.value.mcast_ttl = 4; 
   118                     break;    
   119                 case PR_SockOpt_McastLoopback:
   120                     fd = udp; 
   121                     data.value.mcast_loopback = PR_TRUE; 
   122                     break;    
   123 #endif
   124                 case PR_SockOpt_NoDelay:
   125                     data.value.no_delay = PR_TRUE;         
   126                     break;    
   127 #ifndef WIN32
   128                 case PR_SockOpt_MaxSegment:
   129                     data.value.max_segment = segment;      
   130                     break;    
   131 #endif
   132 #ifndef SYMBIAN
   133                 case PR_SockOpt_Broadcast:
   134                     fd = udp; 
   135                     data.value.broadcast = PR_TRUE;         
   136                     break;    
   137 #endif
   138 #ifdef SO_REUSEPORT
   139                 case PR_SockOpt_Reuseport:
   140                     data.value.reuse_port = PR_TRUE;
   141                     break;
   142 #endif
   143                 default: continue;
   144             }
   146 			/*
   147 			 * TCP_MAXSEG can only be read, not set
   148 			 */
   149             if (option != PR_SockOpt_MaxSegment) {
   150 #ifdef WIN32
   151             	if (option != PR_SockOpt_McastLoopback)
   152 #endif
   153 				{
   154             		rv = PR_SetSocketOption(fd, &data);
   155             		if (PR_FAILURE == rv)
   156 							Failed("PR_SetSocketOption()", tag[option]);
   157 				}
   158 			}
   160             rv = PR_GetSocketOption(fd, &data);
   161             if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]);
   162         }
   163         PR_Close(udp);
   164         PR_Close(tcp);
   165     }
   166     PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED");
   167     return (failed) ? 1 : 0;
   168 }  /* main */
   170 /* sockopt.c */

mercurial