1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/tests/sockopt.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,171 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nspr.h" 1.10 +#include "prio.h" 1.11 +#include "prinit.h" 1.12 +#include "prprf.h" 1.13 +#include "obsolete/probslet.h" 1.14 + 1.15 +#include "plerror.h" 1.16 + 1.17 +#ifdef XP_UNIX 1.18 +#include <sys/socket.h> /* SO_REUSEPORT */ 1.19 +#endif 1.20 + 1.21 +static PRFileDesc *err = NULL; 1.22 +static PRBool failed = PR_FALSE; 1.23 + 1.24 +static void Failed(const char *msg1, const char *msg2) 1.25 +{ 1.26 + if (NULL != msg1) PR_fprintf(err, "%s ", msg1); 1.27 + PL_FPrintError(err, msg2); 1.28 + failed = PR_TRUE; 1.29 +} /* Failed */ 1.30 + 1.31 +static PRSockOption Incr(PRSockOption *option) 1.32 +{ 1.33 + PRIntn val = ((PRIntn)*option) + 1; 1.34 + *option = (PRSockOption)val; 1.35 + return (PRSockOption)val; 1.36 +} /* Incr */ 1.37 + 1.38 +int main(int argc, char **argv) 1.39 +{ 1.40 + PRStatus rv; 1.41 + PRFileDesc *udp = PR_NewUDPSocket(); 1.42 + PRFileDesc *tcp = PR_NewTCPSocket(); 1.43 + const char *tag[] = 1.44 + { 1.45 + "PR_SockOpt_Nonblocking", /* nonblocking io */ 1.46 + "PR_SockOpt_Linger", /* linger on close if data present */ 1.47 + "PR_SockOpt_Reuseaddr", /* allow local address reuse */ 1.48 + "PR_SockOpt_Keepalive", /* keep connections alive */ 1.49 + "PR_SockOpt_RecvBufferSize", /* send buffer size */ 1.50 + "PR_SockOpt_SendBufferSize", /* receive buffer size */ 1.51 + 1.52 + "PR_SockOpt_IpTimeToLive", /* time to live */ 1.53 + "PR_SockOpt_IpTypeOfService", /* type of service and precedence */ 1.54 + 1.55 + "PR_SockOpt_AddMember", /* add an IP group membership */ 1.56 + "PR_SockOpt_DropMember", /* drop an IP group membership */ 1.57 + "PR_SockOpt_McastInterface", /* multicast interface address */ 1.58 + "PR_SockOpt_McastTimeToLive", /* multicast timetolive */ 1.59 + "PR_SockOpt_McastLoopback", /* multicast loopback */ 1.60 + 1.61 + "PR_SockOpt_NoDelay", /* don't delay send to coalesce packets */ 1.62 + "PR_SockOpt_MaxSegment", /* maximum segment size */ 1.63 + "PR_SockOpt_Broadcast", /* Enable broadcast */ 1.64 + "PR_SockOpt_Reuseport", /* allow local address & port reuse */ 1.65 + "PR_SockOpt_Last" 1.66 + }; 1.67 + 1.68 + err = PR_GetSpecialFD(PR_StandardError); 1.69 + PR_STDIO_INIT(); 1.70 + 1.71 + if (NULL == udp) Failed("PR_NewUDPSocket()", NULL); 1.72 + else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL); 1.73 + else 1.74 + { 1.75 + PRSockOption option; 1.76 + PRUint32 segment = 1024; 1.77 + PRNetAddr addr; 1.78 + 1.79 + rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr); 1.80 + if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL); 1.81 + rv = PR_Bind(udp, &addr); 1.82 + if (PR_FAILURE == rv) Failed("PR_Bind()", NULL); 1.83 + for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option)) 1.84 + { 1.85 + PRSocketOptionData data; 1.86 + PRFileDesc *fd = tcp; 1.87 + data.option = option; 1.88 + switch (option) 1.89 + { 1.90 + case PR_SockOpt_Nonblocking: 1.91 + data.value.non_blocking = PR_TRUE; 1.92 + break; 1.93 +#ifndef SYMBIAN 1.94 + case PR_SockOpt_Linger: 1.95 + data.value.linger.polarity = PR_TRUE; 1.96 + data.value.linger.linger = PR_SecondsToInterval(2); 1.97 + break; 1.98 +#endif 1.99 + case PR_SockOpt_Reuseaddr: 1.100 + data.value.reuse_addr = PR_TRUE; 1.101 + break; 1.102 + case PR_SockOpt_Keepalive: 1.103 + data.value.keep_alive = PR_TRUE; 1.104 + break; 1.105 + case PR_SockOpt_RecvBufferSize: 1.106 + data.value.recv_buffer_size = segment; 1.107 + break; 1.108 + case PR_SockOpt_SendBufferSize: 1.109 + data.value.send_buffer_size = segment; 1.110 + break; 1.111 +#ifndef SYMBIAN 1.112 + case PR_SockOpt_IpTimeToLive: 1.113 + data.value.ip_ttl = 64; 1.114 + break; 1.115 + case PR_SockOpt_IpTypeOfService: 1.116 + data.value.tos = 0; 1.117 + break; 1.118 + case PR_SockOpt_McastTimeToLive: 1.119 + fd = udp; 1.120 + data.value.mcast_ttl = 4; 1.121 + break; 1.122 + case PR_SockOpt_McastLoopback: 1.123 + fd = udp; 1.124 + data.value.mcast_loopback = PR_TRUE; 1.125 + break; 1.126 +#endif 1.127 + case PR_SockOpt_NoDelay: 1.128 + data.value.no_delay = PR_TRUE; 1.129 + break; 1.130 +#ifndef WIN32 1.131 + case PR_SockOpt_MaxSegment: 1.132 + data.value.max_segment = segment; 1.133 + break; 1.134 +#endif 1.135 +#ifndef SYMBIAN 1.136 + case PR_SockOpt_Broadcast: 1.137 + fd = udp; 1.138 + data.value.broadcast = PR_TRUE; 1.139 + break; 1.140 +#endif 1.141 +#ifdef SO_REUSEPORT 1.142 + case PR_SockOpt_Reuseport: 1.143 + data.value.reuse_port = PR_TRUE; 1.144 + break; 1.145 +#endif 1.146 + default: continue; 1.147 + } 1.148 + 1.149 + /* 1.150 + * TCP_MAXSEG can only be read, not set 1.151 + */ 1.152 + if (option != PR_SockOpt_MaxSegment) { 1.153 +#ifdef WIN32 1.154 + if (option != PR_SockOpt_McastLoopback) 1.155 +#endif 1.156 + { 1.157 + rv = PR_SetSocketOption(fd, &data); 1.158 + if (PR_FAILURE == rv) 1.159 + Failed("PR_SetSocketOption()", tag[option]); 1.160 + } 1.161 + } 1.162 + 1.163 + rv = PR_GetSocketOption(fd, &data); 1.164 + if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]); 1.165 + } 1.166 + PR_Close(udp); 1.167 + PR_Close(tcp); 1.168 + } 1.169 + PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED"); 1.170 + return (failed) ? 1 : 0; 1.171 +} /* main */ 1.172 + 1.173 +/* sockopt.c */ 1.174 +