151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <errno.h> 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <string.h> 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <sys/types.h> 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <sys/socket.h> 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <netinet/tcp.h> /* Defines TCP_NODELAY, needed for 2.6 */ 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <netinet/in.h> 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <net/if.h> 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <netdb.h> 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <stdlib.h> 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <dlfcn.h> 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <limits.h> 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <sys/param.h> 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef MAXINT 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define MAXINT INT_MAX 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 42f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski#ifdef __BIONIC__ 43f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski#include <linux/ipv6_route.h> 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __solaris__ 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <sys/sockio.h> 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <stropts.h> 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <inet/nd.h> 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __linux__ 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <arpa/inet.h> 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <net/route.h> 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <sys/utsname.h> 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef IPV6_FLOWINFO_SEND 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define IPV6_FLOWINFO_SEND 33 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jni_util.h" 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jvm.h" 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "net_util.h" 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "java_net_SocketOptions.h" 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* needed from libsocket on Solaris 8 */ 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskigetaddrinfo_f getaddrinfo_ptr = NULL; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskifreeaddrinfo_f freeaddrinfo_ptr = NULL; 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskigai_strerror_f gai_strerror_ptr = NULL; 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskigetnameinfo_f getnameinfo_ptr = NULL; 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * EXCLBIND socket options only on Solaris 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(__solaris__) && !defined(TCP_EXCLBIND) 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define TCP_EXCLBIND 0x21 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(__solaris__) && !defined(UDP_EXCLBIND) 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define UDP_EXCLBIND 0x0101 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid setDefaultScopeID(JNIEnv *env, struct sockaddr *him) 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef MACOSX 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static jclass ni_class = NULL; 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static jfieldID ni_defaultIndexID; 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ni_class == NULL) { 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CHECK_NULL(c); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = (*env)->NewGlobalRef(env, c); 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CHECK_NULL(c); 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ni_defaultIndexID = (*env)->GetStaticFieldID( 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski env, c, "defaultIndex", "I"); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ni_class = c; 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int defaultIndex; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)him; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sin6->sin6_family == AF_INET6 && (sin6->sin6_scope_id == 0)) { 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultIndex = (*env)->GetStaticIntField(env, ni_class, 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ni_defaultIndexID); 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sin6->sin6_scope_id = defaultIndex; 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint getDefaultScopeID(JNIEnv *env) { 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static jclass ni_class = NULL; 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static jfieldID ni_defaultIndexID; 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ni_class == NULL) { 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); 115f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski if (c == NULL) return 0; 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = (*env)->NewGlobalRef(env, c); 117f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski if (c == NULL) return 0; 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ni_defaultIndexID = (*env)->GetStaticFieldID( 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski env, c, "defaultIndex", "I"); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ni_class = c; 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int defaultIndex = 0; 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski defaultIndex = (*env)->GetStaticIntField(env, ni_class, 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ni_defaultIndexID); 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return defaultIndex; 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __solaris__ 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int init_tcp_max_buf, init_udp_max_buf; 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int tcp_max_buf; 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int udp_max_buf; 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int useExclBind = 0; 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get the specified parameter from the specified driver. The value 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the parameter is assumed to be an 'int'. If the parameter 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cannot be obtained return -1 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskigetParam(char *driver, char *param) 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct strioctl stri; 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char buf [64]; 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int s; 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int value; 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s = open (driver, O_RDWR); 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s < 0) { 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski strncpy (buf, param, sizeof(buf)); 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stri.ic_cmd = ND_GET; 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stri.ic_timout = 0; 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stri.ic_dp = buf; 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stri.ic_len = sizeof(buf); 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ioctl (s, I_STR, &stri) < 0) { 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = -1; 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski value = atoi(buf); 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close (s); 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return value; 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for Solaris versions that do not support the ioctl() in getParam(). 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Ugly, but only called once (for each sotype). 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 170eb984abe3282ad17cfdea4fdaab96f3029113cb5Yi Kong * As an optimization, we make a guess using the default values for Solaris 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * assuming they haven't been modified with ndd. 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define MAX_TCP_GUESS 1024 * 1024 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define MAX_UDP_GUESS 2 * 1024 * 1024 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define FAIL_IF_NOT_ENOBUFS if (errno != ENOBUFS) return -1 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int findMaxBuf(int fd, int opt, int sotype) { 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int a = 0; 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int b = MAXINT; 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int initial_guess; 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int limit = -1; 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sotype == SOCK_DGRAM) { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initial_guess = MAX_UDP_GUESS; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initial_guess = MAX_TCP_GUESS; 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess, sizeof(int)) == 0) { 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initial_guess++; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess,sizeof(int)) < 0) { 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FAIL_IF_NOT_ENOBUFS; 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return initial_guess - 1; 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a = initial_guess; 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FAIL_IF_NOT_ENOBUFS; 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b = initial_guess - 1; 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int mid = a + (b-a)/2; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (setsockopt(fd, SOL_SOCKET, opt, &mid, sizeof(int)) == 0) { 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski limit = mid; 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a = mid + 1; 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FAIL_IF_NOT_ENOBUFS; 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b = mid - 1; 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while (b >= a); 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return limit; 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __linux__ 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int vinit = 0; 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int kernelV24 = 0; 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int vinit24 = 0; 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint kernelIsV24 () { 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!vinit24) { 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct utsname sysinfo; 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (uname(&sysinfo) == 0) { 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sysinfo.release[3] = '\0'; 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (strcmp(sysinfo.release, "2.4") == 0) { 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski kernelV24 = JNI_TRUE; 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski vinit24 = 1; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return kernelV24; 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint getScopeID (struct sockaddr *him) { 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hext->sin6_scope_id; 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint cmpScopeID (unsigned int scope, struct sockaddr *him) { 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *hext = (struct sockaddr_in6 *)him; 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return hext->sin6_scope_id == scope; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint getScopeID (struct sockaddr *him) { 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him; 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return him6->sin6_scope_id; 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint cmpScopeID (unsigned int scope, struct sockaddr *him) { 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him; 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return him6->sin6_scope_id == scope; 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_ThrowByNameWithLastError(JNIEnv *env, const char *name, 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski const char *defaultDetail) { 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char errmsg[255]; 2666786911a58e65bad88d08a0d1f8d32ab067edaa9George Burgess IV snprintf(errmsg, sizeof(errmsg), "errno: %d, error: %s\n", errno, 2676786911a58e65bad88d08a0d1f8d32ab067edaa9George Burgess IV defaultDetail); 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JNU_ThrowByNameWithLastError(env, name, errmsg); 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_ThrowCurrent(JNIEnv *env, char *msg) { 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski NET_ThrowNew(env, errno, msg); 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char fullMsg[512]; 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!msg) { 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski msg = "no further information"; 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch(errorNumber) { 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case EBADF: 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg); 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg); 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case EINTR: 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", msg); 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski errno = errorNumber; 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", msg); 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskijfieldID 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_GetFileDescriptorID(JNIEnv *env) 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jclass cls = (*env)->FindClass(env, "java/io/FileDescriptor"); 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CHECK_NULL_RETURN(cls, NULL); 303ba7cc9f5357c323a1006119a20ce025fd4c57fd2Piotr Jastrzebski return (*env)->GetFieldID(env, cls, "descriptor", "I"); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(DONT_ENABLE_IPV6) 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskijint IPv6_supported() 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else /* !DONT_ENABLE_IPV6 */ 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskijint IPv6_supported() 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef AF_INET6 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef AF_INET6 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int fd; 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void *ipv6_fn; 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SOCKADDR sa; 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski socklen_t sa_len = sizeof(sa); 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 326ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak // This one below is problematic, will fail without proper permissions 327ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak // and report no ipv6 for some and ipv6 for others. 328ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak //fd = JVM_Socket(AF_INET6, SOCK_STREAM, 0) ; 329ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak //if (fd < 0) { 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TODO: We really cant tell since it may be an unrelated error 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for now we will assume that AF_INET6 is not available 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 334ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak // return JNI_FALSE; 335ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak //} 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If fd 0 is a socket it means we've been launched from inetd or 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * xinetd. If it's a socket then check the family - if it's an 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IPv4 socket then we need to disable IPv6. 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 342ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak /*if (getsockname(0, (struct sockaddr *)&sa, &sa_len) == 0) { 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr *saP = (struct sockaddr *)&sa; 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (saP->sa_family != AF_INET6) { 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 347ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak }*/ 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Linux - check if any interface has an IPv6 address. 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Don't need to parse the line - we just need an indication. 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __linux__ 354ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak /* { 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FILE *fP = fopen("/proc/net/if_inet6", "r"); 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char buf[255]; 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char *bufP; 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fP == NULL) { 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(fd); 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bufP = fgets(buf, sizeof(buf), fP); 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fclose(fP); 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bufP == NULL) { 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(fd); 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 369ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak }*/ 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Solaris 8 it's possible to create INET6 sockets even 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * though IPv6 is not enabled on all interfaces. Thus we 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * query the number of IPv6 addresses to verify that IPv6 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * has been configured on at least one interface. 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Linux it doesn't matter - if IPv6 is built-in the 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * kernel then IPv6 addresses will be bound automatically 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to all interfaces. 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __solaris__ 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef SIOCGLIFNUM 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct lifnum numifs; 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numifs.lifn_family = AF_INET6; 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski numifs.lifn_flags = 0; 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ioctl(fd, SIOCGLIFNUM, (char *)&numifs) < 0) { 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SIOCGLIFNUM failed - assume IPv6 not configured 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 394a87f559f13ebd0861c0dfbb95b51e76311c94473Yi Kong untagSocket(env, fd); 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(fd); 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If no IPv6 addresses then return false. If count > 0 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it's possible that all IPv6 addresses are "down" but 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that's okay as they may be brought "up" while the 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * VM is running. 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (numifs.lifn_count == 0) { 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(fd); 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* SIOCGLIFNUM not defined in build environment ??? */ 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(fd); 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* __solaris */ 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * OK we may have the stack available in the kernel, 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * we should also check if the APIs are available. 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4219b7a4b3eb9a9a1d0a25416bd914cdd46109146c5Przemyslaw Szczepaniak 422ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton"); 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ipv6_fn == NULL ) { 424ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak // close(fd); 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_FALSE; 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * We've got the library, let's get the pointers to some 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IPV6 specific functions. We have to do that because, at least 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on Solaris we may build on a system without IPV6 networking 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * libraries, therefore we can't have a hard link to these 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * functions. 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getaddrinfo_ptr = (getaddrinfo_f) 436ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak JVM_FindLibraryEntry(RTLD_DEFAULT, "getaddrinfo"); 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski freeaddrinfo_ptr = (freeaddrinfo_f) 439ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo"); 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gai_strerror_ptr = (gai_strerror_f) 442ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror"); 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getnameinfo_ptr = (getnameinfo_f) 445ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo"); 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) { 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* We need all 3 of them */ 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getaddrinfo_ptr = NULL; 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 452ae218d9bdc8395ac0ed9278c86cff597915c2a7bPrzemyslaw Szczepaniak //close(fd); 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return JNI_TRUE; 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* AF_INET6 */ 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* DONT_ENABLE_IPV6 */ 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski const char* hostname, 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int gai_error) 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int size; 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char *buf; 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski const char *format = "%s: %s"; 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski const char *error_string = 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error); 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (error_string == NULL) 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski error_string = "unknown error"; 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski buf = (char *) malloc(size); 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (buf) { 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jstring s; 4746786911a58e65bad88d08a0d1f8d32ab067edaa9George Burgess IV snprintf(buf, size, format, hostname, error_string); 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s = JNU_NewStringPlatform(env, buf); 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s != NULL) { 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jobject x = JNU_NewObjectByName(env, 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "java/net/UnknownHostException", 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "(Ljava/lang/String;)V", s); 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (x != NULL) 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (*env)->Throw(env, x); 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski free(buf); 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_AllocSockaddr(struct sockaddr **him, int *len) { 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef AF_INET6 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ipv6_available()) { 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *him6 = (struct sockaddr_in6*)malloc(sizeof(struct sockaddr_in6)); 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *him = (struct sockaddr*)him6; 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *len = sizeof(struct sockaddr_in6); 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* AF_INET6 */ 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in *him4 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *him = (struct sockaddr*)him4; 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *len = sizeof(struct sockaddr_in); 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5033442abd5bcb4d4d0bfdcc08bf660cbf61ae82bf8Yi Kong#if 0 5043442abd5bcb4d4d0bfdcc08bf660cbf61ae82bf8Yi Kong// Android-changed: Stripped out unused code. http://b/33250070 5053442abd5bcb4d4d0bfdcc08bf660cbf61ae82bf8Yi Kong// #if defined(__linux__) && defined(AF_INET6) 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* following code creates a list of addresses from the kernel 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * routing table that are routed via the loopback address. 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * We check all destination addresses against this table 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and override the scope_id field to use the relevant value for "lo" 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in order to work-around the Linux bug that prevents packets destined 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for certain local addresses from being sent via a physical interface. 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistruct loopback_route { 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct in6_addr addr; /* destination address */ 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int plen; /* prefix length */ 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}; 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic struct loopback_route *loRoutes = 0; 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int nRoutes = 0; /* number of routes */ 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int loRoutes_size = 16; /* initial size */ 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int lo_scope_id = 0; 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic void initLoopbackRoutes(); 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid printAddr (struct in6_addr *addr) { 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i; 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (i=0; i<16; i++) { 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski printf ("%02x", addr->s6_addr[i]); 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski printf ("\n"); 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic void initLoopbackRoutes() { 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FILE *f; 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char srcp[8][5]; 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char hopp[8][5]; 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dest_plen, src_plen, use, refcnt, metric; 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unsigned long flags; 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char dest_str[40]; 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct in6_addr dest_addr; 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char device[16]; 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (loRoutes != 0) { 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski free (loRoutes); 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski loRoutes = calloc (loRoutes_size, sizeof(struct loopback_route)); 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (loRoutes == 0) { 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Scan /proc/net/ipv6_route looking for a matching 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * route. 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((f = fopen("/proc/net/ipv6_route", "r")) == NULL) { 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ; 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "%4s%4s%4s%4s%4s%4s%4s%4s %02x " 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "%4s%4s%4s%4s%4s%4s%4s%4s " 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "%08x %08x %08x %08lx %8s", 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str, &dest_str[5], &dest_str[10], &dest_str[15], 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &dest_str[20], &dest_str[25], &dest_str[30], &dest_str[35], 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &dest_plen, 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski srcp[0], srcp[1], srcp[2], srcp[3], 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski srcp[4], srcp[5], srcp[6], srcp[7], 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &src_plen, 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hopp[0], hopp[1], hopp[2], hopp[3], 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hopp[4], hopp[5], hopp[6], hopp[7], 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &metric, &use, &refcnt, &flags, device) == 31) { 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Some routes should be ignored 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ( (dest_plen < 0 || dest_plen > 128) || 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (src_plen != 0) || 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (flags & (RTF_POLICY | RTF_FLOW)) || 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((flags & RTF_REJECT) && dest_plen == 0) ) { 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Convert the destination address 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[4] = ':'; 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[9] = ':'; 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[14] = ':'; 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[19] = ':'; 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[24] = ':'; 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[29] = ':'; 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[34] = ':'; 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski dest_str[39] = '\0'; 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (inet_pton(AF_INET6, dest_str, &dest_addr) < 0) { 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* not an Ipv6 address */ 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (strcmp(device, "lo") != 0) { 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Not a loopback route */ 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nRoutes == loRoutes_size) { 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski loRoutes = realloc (loRoutes, loRoutes_size * 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sizeof (struct loopback_route) * 2); 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (loRoutes == 0) { 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ; 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski loRoutes_size *= 2; 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski memcpy (&loRoutes[nRoutes].addr,&dest_addr,sizeof(struct in6_addr)); 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski loRoutes[nRoutes].plen = dest_plen; 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nRoutes ++; 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fclose (f); 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* now find the scope_id for "lo" */ 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char devname[21]; 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char addr6p[8][5]; 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int plen, scope, dad_status, if_idx; 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((f = fopen("/proc/net/if_inet6", "r")) != NULL) { 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addr6p[0], addr6p[1], addr6p[2], addr6p[3], 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addr6p[4], addr6p[5], addr6p[6], addr6p[7], 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &if_idx, &plen, &scope, &dad_status, devname) == 13) { 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (strcmp(devname, "lo") == 0) { 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Found - so just return the index 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fclose(f); 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lo_scope_id = if_idx; 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fclose(f); 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Following is used for binding to local addresses. Equivalent 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to code above, for bind(). 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistruct localinterface { 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index; 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char localaddr [16]; 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}; 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic struct localinterface *localifs = 0; 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int localifsSize = 0; /* size of array */ 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic int nifs = 0; /* number of entries used in array */ 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* not thread safe: make sure called once from one thread */ 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic void initLocalIfs () { 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FILE *f; 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unsigned char staddr [16]; 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski char ifname [33]; 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct localinterface *lif=0; 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int index, x1, x2, x3; 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unsigned int u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,ua,ub,uc,ud,ue,uf; 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((f = fopen("/proc/net/if_inet6", "r")) == NULL) { 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ; 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (fscanf (f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x " 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "%d %x %x %x %32s",&u0,&u1,&u2,&u3,&u4,&u5,&u6,&u7, 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &u8,&u9,&ua,&ub,&uc,&ud,&ue,&uf, 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &index, &x1, &x2, &x3, ifname) == 21) { 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[0] = (unsigned char)u0; 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[1] = (unsigned char)u1; 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[2] = (unsigned char)u2; 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[3] = (unsigned char)u3; 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[4] = (unsigned char)u4; 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[5] = (unsigned char)u5; 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[6] = (unsigned char)u6; 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[7] = (unsigned char)u7; 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[8] = (unsigned char)u8; 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[9] = (unsigned char)u9; 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[10] = (unsigned char)ua; 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[11] = (unsigned char)ub; 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[12] = (unsigned char)uc; 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[13] = (unsigned char)ud; 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[14] = (unsigned char)ue; 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski staddr[15] = (unsigned char)uf; 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nifs ++; 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nifs > localifsSize) { 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localifs = (struct localinterface *) realloc ( 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localifs, sizeof (struct localinterface)* (localifsSize+5)); 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (localifs == 0) { 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nifs = 0; 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fclose (f); 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lif = localifs + localifsSize; 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski localifsSize += 5; 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lif ++; 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski memcpy (lif->localaddr, staddr, 16); 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lif->index = index; 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fclose (f); 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid initLocalAddrTable () { 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initLoopbackRoutes(); 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski initLocalIfs(); 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid initLocalAddrTable () {} 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid parseExclusiveBindProperty(JNIEnv *env) { 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __solaris__ 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jstring s, flagSet; 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jclass iCls; 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jmethodID mid; 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind"); 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CHECK_NULL(s); 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski iCls = (*env)->FindClass(env, "java/lang/System"); 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CHECK_NULL(iCls); 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mid = (*env)->GetStaticMethodID(env, iCls, "getProperty", 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "(Ljava/lang/String;)Ljava/lang/String;"); 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski CHECK_NULL(mid); 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flagSet != NULL) { 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski useExclBind = 1; 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* In the case of an IPv4 Inetaddress this method will return an 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE. 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress. 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*/ 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT int JNICALL 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int *len, jboolean v4MappedAddress) { 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jint family; 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski family = getInetAddress_family(env, iaObj); 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef AF_INET6 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* needs work. 1. family 2. clean up him6 etc deallocate memory */ 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ipv6_available() && !(family == IPv4 && v4MappedAddress == JNI_FALSE)) { 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him; 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jbyteArray ipaddress; 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jbyte caddr[16]; 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jint address; 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == IPv4) { /* will convert to IPv4-mapped address */ 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski memset((char *) caddr, 0, 16); 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski address = getInetAddress_addr(env, iaObj); 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (address == INADDR_ANY) { 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* we would always prefer IPv6 wildcard address 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[10] = 0xff; 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[11] = 0xff; */ 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[10] = 0xff; 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[11] = 0xff; 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[12] = ((address >> 24) & 0xff); 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[13] = ((address >> 16) & 0xff); 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[14] = ((address >> 8) & 0xff); 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski caddr[15] = (address & 0xff); 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 77762e0b4793b755083e94aac458111ca347314adddYi Kong getInet6Address_ipaddress(env, iaObj, (char *)caddr); 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski memset((char *)him6, 0, sizeof(struct sockaddr_in6)); 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski him6->sin6_port = htons(port); 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) ); 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski him6->sin6_family = AF_INET6; 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *len = sizeof(struct sockaddr_in6) ; 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(_ALLBSD_SOURCE) && defined(_AF_INET6) 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// XXXBSD: should we do something with scope id here ? see below linux comment 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* MMM: Come back to this! */ 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79037980c1a826a1eb83b2c825d533c70c7d041e054Narayan Kamath // Android-changed: Don't try and figure out scope_ids for link local 79137980c1a826a1eb83b2c825d533c70c7d041e054Narayan Kamath // addresses. Use them only if they're set in java (say, if the Inet6Address 79237980c1a826a1eb83b2c825d533c70c7d041e054Narayan Kamath // was constructed with a specific scope_id or NetworkInterface). 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family != IPv4) { 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ia6_scopeidID) { 79562e0b4793b755083e94aac458111ca347314adddYi Kong int scope_id = getInet6Address_scopeid(env, iaObj); 79637980c1a826a1eb83b2c825d533c70c7d041e054Narayan Kamath if (scope_id > 0) { 79737980c1a826a1eb83b2c825d533c70c7d041e054Narayan Kamath him6->sin6_scope_id = scope_id; 79837980c1a826a1eb83b2c825d533c70c7d041e054Narayan Kamath } 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* AF_INET6 */ 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in *him4 = (struct sockaddr_in*)him; 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jint address; 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (family == IPv6) { 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable"); 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski memset((char *) him4, 0, sizeof(struct sockaddr_in)); 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski address = getInetAddress_addr(env, iaObj); 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski him4->sin_port = htons((short) port); 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski him4->sin_addr.s_addr = (uint32_t) htonl(address); 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski him4->sin_family = AF_INET; 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *len = sizeof(struct sockaddr_in); 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskivoid 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_SetTrafficClass(struct sockaddr *him, int trafficClass) { 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef AF_INET6 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (him->sa_family == AF_INET6) { 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him; 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski him6->sin6_flowinfo = htonl((trafficClass & 0xff) << 20); 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* AF_INET6 */ 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT jint JNICALL 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_GetPortFromSockaddr(struct sockaddr *him) { 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef AF_INET6 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (him->sa_family == AF_INET6) { 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ntohs(((struct sockaddr_in6*)him)->sin6_port); 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif /* AF_INET6 */ 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ntohs(((struct sockaddr_in*)him)->sin_port); 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_IsIPv4Mapped(jbyte* caddr) { 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i; 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (i = 0; i < 10; i++) { 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (caddr[i] != 0x00) { 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; /* false */ 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (((caddr[10] & 0xff) == 0xff) && ((caddr[11] & 0xff) == 0xff)) { 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 1; /* true */ 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; /* false */ 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_IPv4MappedToIPv4(jbyte* caddr) { 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((caddr[12] & 0xff) << 24) | ((caddr[13] & 0xff) << 16) | ((caddr[14] & 0xff) << 8) 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski | (caddr[15] & 0xff); 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_IsEqual(jbyte* caddr1, jbyte* caddr2) { 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i; 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (i = 0; i < 16; i++) { 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (caddr1[i] != caddr2[i]) { 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; /* false */ 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 1; 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskijboolean NET_addrtransAvailable() { 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (jboolean)(getaddrinfo_ptr != NULL); 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint NET_IsZeroAddr(jbyte* caddr) { 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i; 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (i = 0; i < 16; i++) { 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (caddr[i] != 0) { 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 1; 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Map the Java level socket option to the platform specific 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * level and option name. 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_MapSocketOption(jint cmd, int *level, int *optname) { 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static struct { 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jint cmd; 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int level; 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int optname; 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } const opts[] = { 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_TCP_NODELAY, IPPROTO_TCP, TCP_NODELAY }, 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_OOBINLINE, SOL_SOCKET, SO_OOBINLINE }, 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_LINGER, SOL_SOCKET, SO_LINGER }, 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF }, 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF }, 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE }, 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR }, 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST }, 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS }, 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF }, 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_IP_MULTICAST_IF2, IPPROTO_IP, IP_MULTICAST_IF }, 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { java_net_SocketOptions_IP_MULTICAST_LOOP, IPPROTO_IP, IP_MULTICAST_LOOP }, 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i; 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef AF_INET6 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ipv6_available()) { 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (cmd) { 919780a0e6392567eb5d1c3425043b092d29590976bYi Kong // Different multicast options if IPv6 is enabled 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case java_net_SocketOptions_IP_MULTICAST_IF: 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case java_net_SocketOptions_IP_MULTICAST_IF2: 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *level = IPPROTO_IPV6; 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *optname = IPV6_MULTICAST_IF; 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case java_net_SocketOptions_IP_MULTICAST_LOOP: 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *level = IPPROTO_IPV6; 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *optname = IPV6_MULTICAST_LOOP; 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 930780a0e6392567eb5d1c3425043b092d29590976bYi Kong#if (defined(__solaris__) || defined(MACOSX)) 931780a0e6392567eb5d1c3425043b092d29590976bYi Kong // Map IP_TOS request to IPV6_TCLASS 932780a0e6392567eb5d1c3425043b092d29590976bYi Kong case java_net_SocketOptions_IP_TOS: 933780a0e6392567eb5d1c3425043b092d29590976bYi Kong *level = IPPROTO_IPV6; 934780a0e6392567eb5d1c3425043b092d29590976bYi Kong *optname = IPV6_TCLASS; 935780a0e6392567eb5d1c3425043b092d29590976bYi Kong return 0; 936780a0e6392567eb5d1c3425043b092d29590976bYi Kong#endif 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Map the Java level option to the native level 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) { 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cmd == opts[i].cmd) { 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *level = opts[i].level; 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *optname = opts[i].optname; 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* not found */ 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Wrapper for getsockopt system routine - does any necessary 958eb984abe3282ad17cfdea4fdaab96f3029113cb5Yi Kong * pre/post processing to deal with OS specific oddities :- 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Linux the SO_SNDBUF/SO_RCVBUF values must be post-processed 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to compensate for an incorrect value returned by the kernel. 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_GetSockOpt(int fd, int level, int opt, void *result, 96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int *len) 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rv; 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __solaris__ 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rv = getsockopt(fd, level, opt, result, len); 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski socklen_t socklen = *len; 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rv = getsockopt(fd, level, opt, result, &socklen); 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *len = socklen; 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rv < 0) { 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return rv; 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __linux__ 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Linux SO_SNDBUF/SO_RCVBUF aren't symmetric. This 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stems from additional socket structures in the send 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and receive buffers. 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((level == SOL_SOCKET) && ((opt == SO_SNDBUF) 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski || (opt == SO_RCVBUF))) { 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = *((int *)result); 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n /= 2; 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *((int *)result) = n; 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* Workaround for Mac OS treating linger value as 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * signed integer 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef MACOSX 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == SOL_SOCKET && opt == SO_LINGER) { 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct linger* to_cast = (struct linger*)result; 100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski to_cast->l_linger = (unsigned short)to_cast->l_linger; 100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return rv; 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Wrapper for setsockopt system routine - performs any 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * necessary pre/post processing to deal with OS specific 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * issue :- 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Solaris need to limit the suggested value for SO_SNDBUF 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and SO_RCVBUF to the kernel configured limit 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For IP_TOS socket option need to mask off bits as this 101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * aren't automatically masked by the kernel and results in 1019780a0e6392567eb5d1c3425043b092d29590976bYi Kong * an error. 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_SetSockOpt(int fd, int level, int opt, const void *arg, 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int len) 102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef IPTOS_TOS_MASK 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define IPTOS_TOS_MASK 0x1e 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef IPTOS_PREC_MASK 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define IPTOS_PREC_MASK 0xe0 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(_ALLBSD_SOURCE) 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(KIPC_MAXSOCKBUF) 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int mib[3]; 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski size_t rlen; 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int *bufsize; 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __APPLE__ 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static int maxsockbuf = -1; 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static long maxsockbuf = -1; 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IPPROTO/IP_TOS :- 1049780a0e6392567eb5d1c3425043b092d29590976bYi Kong * 1. IPv6 on Solaris/Mac OS: 1050780a0e6392567eb5d1c3425043b092d29590976bYi Kong * Set the TOS OR Traffic Class value to cater for 1051780a0e6392567eb5d1c3425043b092d29590976bYi Kong * IPv6 and IPv4 scenarios. 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2. IPv6 on Linux: By default Linux ignores flowinfo 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * field so enable IPV6_FLOWINFO_SEND so that flowinfo 1054780a0e6392567eb5d1c3425043b092d29590976bYi Kong * will be examined. We also set the IPv4 TOS option in this case. 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3. IPv4: set socket option based on ToS and Precedence 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * fields (otherwise get invalid argument) 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == IPPROTO_IP && opt == IP_TOS) { 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int *iptos; 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(AF_INET6) && defined(__linux__) 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ipv6_available()) { 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int optval = 1; 1064780a0e6392567eb5d1c3425043b092d29590976bYi Kong if (setsockopt(fd, IPPROTO_IPV6, IPV6_FLOWINFO_SEND, 1065780a0e6392567eb5d1c3425043b092d29590976bYi Kong (void *)&optval, sizeof(optval)) < 0) { 1066780a0e6392567eb5d1c3425043b092d29590976bYi Kong return -1; 1067780a0e6392567eb5d1c3425043b092d29590976bYi Kong } 1068780a0e6392567eb5d1c3425043b092d29590976bYi Kong /* 1069780a0e6392567eb5d1c3425043b092d29590976bYi Kong * Let's also set the IPV6_TCLASS flag. 1070780a0e6392567eb5d1c3425043b092d29590976bYi Kong * Linux appears to allow both IP_TOS and IPV6_TCLASS to be set 1071780a0e6392567eb5d1c3425043b092d29590976bYi Kong * This helps in mixed environments where IPv4 and IPv6 sockets 1072780a0e6392567eb5d1c3425043b092d29590976bYi Kong * are connecting. 1073780a0e6392567eb5d1c3425043b092d29590976bYi Kong */ 1074780a0e6392567eb5d1c3425043b092d29590976bYi Kong if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, 1075780a0e6392567eb5d1c3425043b092d29590976bYi Kong arg, len) < 0) { 1076780a0e6392567eb5d1c3425043b092d29590976bYi Kong return -1; 1077780a0e6392567eb5d1c3425043b092d29590976bYi Kong } 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski iptos = (int *)arg; 1082780a0e6392567eb5d1c3425043b092d29590976bYi Kong // Android-changed: This is out-dated RFC 1349 scheme. Modern Linux uses 1083780a0e6392567eb5d1c3425043b092d29590976bYi Kong // Diffsev/ECN, and this mask is no longer relavant. 1084780a0e6392567eb5d1c3425043b092d29590976bYi Kong // *iptos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK); 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the value when it exceeds the system limit. 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __solaris__ 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == SOL_SOCKET) { 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sotype=0, arglen; 109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int *bufsize, maxbuf; 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ret; 109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Attempt with the original size */ 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ret = setsockopt(fd, level, opt, arg, len); 110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ret == 0) || (ret == -1 && errno != ENOBUFS)) 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ret; 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Exceeded system limit so clamp and retry */ 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski arglen = sizeof(sotype); 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &arglen) < 0) { 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * We try to get tcp_maxbuf (and udp_max_buf) using 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an ioctl() that isn't available on all versions of Solaris. 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If that fails, we use the search algorithm in findMaxBuf() 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!init_tcp_max_buf && sotype == SOCK_STREAM) { 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf"); 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tcp_max_buf == -1) { 111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM); 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tcp_max_buf == -1) { 112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski init_tcp_max_buf = 1; 112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) { 112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski udp_max_buf = getParam("/dev/udp", "udp_max_buf"); 112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (udp_max_buf == -1) { 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM); 112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (udp_max_buf == -1) { 113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski init_udp_max_buf = 1; 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf; 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bufsize = (int *)arg; 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (*bufsize > maxbuf) { 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *bufsize = maxbuf; 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Linux the receive buffer is used for both socket 114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * structures and the the packet payload. The implication 114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is that if SO_RCVBUF is too small then small packets 1149780a0e6392567eb5d1c3425043b092d29590976bYi Kong * must be discarded. 115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __linux__ 115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == SOL_SOCKET && opt == SO_RCVBUF) { 115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int *bufsize = (int *)arg; 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (*bufsize < 1024) { 115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *bufsize = 1024; 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(_ALLBSD_SOURCE) 116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On FreeBSD need to 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ensure that value is <= kern.ipc.maxsockbuf as otherwise we get 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an ENOBUFS error. 116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == SOL_SOCKET) { 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (opt == SO_SNDBUF || opt == SO_RCVBUF) { 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef KIPC_MAXSOCKBUF 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (maxsockbuf == -1) { 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mib[0] = CTL_KERN; 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mib[1] = KERN_IPC; 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mib[2] = KIPC_MAXSOCKBUF; 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rlen = sizeof(maxsockbuf); 117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sysctl(mib, 3, &maxsockbuf, &rlen, NULL, 0) == -1) 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maxsockbuf = 1024; 117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if 1 117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* XXXBSD: This is a hack to workaround mb_max/mb_max_adj 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski problem. It should be removed when kern.ipc.maxsockbuf 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski will be real value. */ 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maxsockbuf = (maxsockbuf/5)*4; 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#elif defined(__OpenBSD__) 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maxsockbuf = SB_MAX; 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski maxsockbuf = 64 * 1024; /* XXX: NetBSD */ 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bufsize = (int *)arg; 119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (*bufsize > maxsockbuf) { 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *bufsize = maxsockbuf; 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (opt == SO_RCVBUF && *bufsize < 1024) { 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *bufsize = 1024; 119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Solaris, SO_REUSEADDR will allow multiple datagram 120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sockets to bind to the same port. The network jck tests 120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for this "feature", so we need to emulate it by turning on 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SO_REUSEPORT as well for that combination. 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (level == SOL_SOCKET && opt == SO_REUSEADDR) { 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int sotype; 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski socklen_t arglen; 121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski arglen = sizeof(sotype); 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen) < 0) { 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sotype == SOCK_DGRAM) { 1218780a0e6392567eb5d1c3425043b092d29590976bYi Kong setsockopt(fd, level, SO_REUSEPORT, arg, len); 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return setsockopt(fd, level, opt, arg, len); 122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Wrapper for bind system call - performs any necessary pre/post 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * processing to deal with OS specific issues :- 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Linux allows a socket to bind to 127.0.0.255 which must be 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * caught. 123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On Solaris with IPv6 enabled we must use an exclusive 123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * bind to guaranteed a unique port number across the IPv4 and 123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IPv6 port spaces. 123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiint 124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_Bind(int fd, struct sockaddr *him, int len) 124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(__solaris__) && defined(AF_INET6) 124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int level = -1; 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int exclbind = -1; 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rv; 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __linux__ 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ## get bugId for this issue - goes back to 1.2.2 port ## 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ## When IPv6 is enabled this will be an IPv4-mapped 125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ## with family set to AF_INET6 125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (him->sa_family == AF_INET) { 125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct sockaddr_in *sa = (struct sockaddr_in *)him; 125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((ntohl(sa->sin_addr.s_addr) & 0x7f0000ff) == 0x7f0000ff) { 125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski errno = EADDRNOTAVAIL; 125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(__solaris__) && defined(AF_INET6) 126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Solaris has seperate IPv4 and IPv6 port spaces so we 126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * use an exclusive bind when SO_REUSEADDR is not used to 126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * give the illusion of a unified port space. 126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This also avoids problems with IPv6 sockets connecting 126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to IPv4 mapped addresses whereby the socket conversion 127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * results in a late bind that fails because the 127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * corresponding IPv4 port is in use. 127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ipv6_available()) { 127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int arg, len; 127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len = sizeof(arg); 127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (char *)&arg, &len) == 0) { 127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (useExclBind || arg == 0) { 128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SO_REUSEADDR is disabled or sun.net.useExclusiveBind 128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * property is true so enable TCP_EXCLBIND or 128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * UDP_EXCLBIND 128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski len = sizeof(arg); 128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg, 128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski &len) == 0) { 128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (arg == SOCK_STREAM) { 128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = IPPROTO_TCP; 129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski exclbind = TCP_EXCLBIND; 129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski level = IPPROTO_UDP; 129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski exclbind = UDP_EXCLBIND; 129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski arg = 1; 129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setsockopt(fd, level, exclbind, (char *)&arg, 129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sizeof(arg)); 130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rv = bind(fd, him, len); 130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#if defined(__solaris__) && defined(AF_INET6) 130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rv < 0) { 131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int en = errno; 131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* Restore *_EXCLBIND if the bind fails */ 131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (exclbind != -1) { 131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int arg = 0; 131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setsockopt(fd, level, exclbind, (char *)&arg, 131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sizeof(arg)); 131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski errno = en; 131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return rv; 132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Wrapper for select/poll with timeout on a single file descriptor. 132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * flags (defined in net_util_md.h can be any combination of 132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * NET_WAIT_READ, NET_WAIT_WRITE & NET_WAIT_CONNECT. 132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The function will return when either the socket is ready for one 1331780a0e6392567eb5d1c3425043b092d29590976bYi Kong * of the specified operations or the timeout expired. 133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It returns the time left from the timeout (possibly 0), or -1 if it expired. 133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskijint 133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiNET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) 133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jlong prevTime = JVM_CurrentTimeMillis(env, 0); 134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jint read_rv; 134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (1) { 134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jlong newTime; 134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef USE_SELECT 134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct pollfd pfd; 134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pfd.fd = fd; 134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pfd.events = 0; 134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flags & NET_WAIT_READ) 135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pfd.events |= POLLIN; 135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flags & NET_WAIT_WRITE) 135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pfd.events |= POLLOUT; 135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flags & NET_WAIT_CONNECT) 135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pfd.events |= POLLOUT; 135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski errno = 0; 135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski read_rv = NET_Poll(&pfd, 1, timeout); 135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else 136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fd_set rd, wr, ex; 136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski struct timeval t; 136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski t.tv_sec = timeout / 1000; 136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski t.tv_usec = (timeout % 1000) * 1000; 136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_ZERO(&rd); 136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_ZERO(&wr); 136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_ZERO(&ex); 137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flags & NET_WAIT_READ) { 137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_SET(fd, &rd); 137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flags & NET_WAIT_WRITE) { 137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_SET(fd, &wr); 137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (flags & NET_WAIT_CONNECT) { 137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_SET(fd, &wr); 137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FD_SET(fd, &ex); 137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski errno = 0; 138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski read_rv = NET_Select(fd+1, &rd, &wr, &ex, &t); 138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif 138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski newTime = JVM_CurrentTimeMillis(env, 0); 138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski timeout -= (newTime - prevTime); 138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (timeout <= 0) { 138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return read_rv > 0 ? 0 : -1; 139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1391d0860af7cc7e4d5c29fcccc97c66121b7c8cd226Przemyslaw Szczepaniak prevTime = newTime; 139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (read_rv > 0) { 139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } /* while */ 139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return timeout; 140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 140255cf88a557325b05e27443c6ce28ed4d652bf471Yi Kong 14033442abd5bcb4d4d0bfdcc08bf660cbf61ae82bf8Yi Kong#if 0 14043442abd5bcb4d4d0bfdcc08bf660cbf61ae82bf8Yi Kong// Stripped out unused code. 140555cf88a557325b05e27443c6ce28ed4d652bf471Yi Kong// http://b/27301951 140655cf88a557325b05e27443c6ce28ed4d652bf471Yi Kong__attribute__((destructor)) 140755cf88a557325b05e27443c6ce28ed4d652bf471Yi Kongstatic void netUtilCleanUp() { 140855cf88a557325b05e27443c6ce28ed4d652bf471Yi Kong if (loRoutes != 0) free(loRoutes); 140955cf88a557325b05e27443c6ce28ed4d652bf471Yi Kong if (localifs != 0) free(localifs); 141055cf88a557325b05e27443c6ce28ed4d652bf471Yi Kong} 14113442abd5bcb4d4d0bfdcc08bf660cbf61ae82bf8Yi Kong#endif 1412