diff options
Diffstat (limited to 'pr/src/io/prmapopt.c')
-rw-r--r-- | pr/src/io/prmapopt.c | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/pr/src/io/prmapopt.c b/pr/src/io/prmapopt.c index b6653e4b..375a73d2 100644 --- a/pr/src/io/prmapopt.c +++ b/pr/src/io/prmapopt.c @@ -33,6 +33,15 @@ #include "primpl.h" +#if defined(LINUX) || defined(ANDROID) +#include <netinet/in.h> +#endif + +#ifdef DARWIN +#include <netinet/in.h> +#include <netinet/ip.h> +#endif + #ifdef HAVE_NETINET_TCP_H #include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */ #endif @@ -174,6 +183,28 @@ PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionDat (char*)&data->value.mcast_if.inet.ip, &length); break; } + case PR_SockOpt_DontFrag: + { +#if !defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && !defined(ANDROID) + PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); + rv = PR_FAILURE; +#else +#ifdef WIN32 /* Winsock */ + DWORD value; +#else + PRIntn value; +#endif + length = sizeof(value); + rv = _PR_MD_GETSOCKOPT( + fd, level, name, (char*)&value, &length); +#if defined(WIN32) || defined(DARWIN) + data->value.dont_fragment = value; +#else + data->value.dont_fragment = (value == IP_PMTUDISC_DO) ? 1 : 0; +#endif +#endif /* !(!defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && !defined(ANDROID)) */ + break; + } default: PR_NOT_REACHED("Unknown socket option"); break; @@ -306,6 +337,27 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt sizeof(data->value.mcast_if.inet.ip)); break; } + case PR_SockOpt_DontFrag: + { +#if !defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && !defined(ANDROID) + PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0); + rv = PR_FAILURE; +#else +#if defined(WIN32) /* Winsock */ + DWORD value; + value = (data->value.dont_fragment) ? 1 : 0; +#elif defined(LINUX) || defined(ANDROID) + PRIntn value; + value = (data->value.dont_fragment) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; +#elif defined(DARWIN) + PRIntn value; + value = data->value.dont_fragment; +#endif + rv = _PR_MD_SETSOCKOPT( + fd, level, name, (char*)&value, sizeof(value)); +#endif /* !(!defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && !defined(ANDROID)) */ + break; + } default: PR_NOT_REACHED("Unknown socket option"); break; @@ -400,6 +452,23 @@ PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOpt #define IP_TOS _PR_NO_SUCH_SOCKOPT #endif +/* set/get IP do not fragment */ +#if defined(WIN32) +#ifndef IP_DONTFRAGMENT +#define IP_DONTFRAGMENT _PR_NO_SUCH_SOCKOPT +#endif + +#elif defined(LINUX) || defined(ANDROID) +#ifndef IP_MTU_DISCOVER +#define IP_MTU_DISCOVER _PR_NO_SUCH_SOCKOPT +#endif + +#elif defined(DARWIN) +#ifndef IP_DONTFRAG +#define IP_DONTFRAG _PR_NO_SUCH_SOCKOPT +#endif +#endif + #ifndef TCP_NODELAY /* don't delay to coalesce data */ #define TCP_NODELAY _PR_NO_SUCH_SOCKOPT #endif @@ -424,14 +493,23 @@ PRStatus _PR_MapOptionName( 0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF, IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, - TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST, SO_REUSEPORT + TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST, SO_REUSEPORT, +#if defined(WIN32) + IP_DONTFRAGMENT, +#elif defined(LINUX) || defined(ANDROID) + IP_MTU_DISCOVER, +#elif defined(DARWIN) + IP_DONTFRAG, +#else + _PR_NO_SUCH_SOCKOPT, +#endif }; static PRInt32 socketLevels[PR_SockOpt_Last] = { 0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, - IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET, SOL_SOCKET + IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET, SOL_SOCKET, IPPROTO_IP }; if ((optname < PR_SockOpt_Linger) |