jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
author michaelm
Wed, 26 Feb 2014 16:18:08 +0000
changeset 23023 c1aebf9d16a9
parent 23015 73b21ab36615
child 23564 62146f638e22
permissions -rw-r--r--
8035653: InetAddress.getLocalHost crash Reviewed-by: chegar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 22069
diff changeset
     2
 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
#include <windows.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#include <winsock2.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#include "jni.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
#include "net_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include "java_net_DualStackPlainDatagramSocketImpl.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * This function "purges" all outstanding ICMP port unreachable packets
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * outstanding on a socket and returns JNI_TRUE if any ICMP messages
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * have been purged. The rational for purging is to emulate normal BSD
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * behaviour whereby receiving a "connection reset" status resets the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * socket.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
    jboolean got_icmp = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    char buf[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    fd_set tbl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    struct timeval t = { 0, 0 };
22069
d55e36f6c0c9 7102702: java/net/PortUnreachableException/OneExceptionOnly.java failing
msheppar
parents: 18253
diff changeset
    44
    SOCKETADDRESS rmtaddr;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    int addrlen = sizeof(rmtaddr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
     * Peek at the queue to see if there is an ICMP port unreachable. If there
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
     * is then receive it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    FD_ZERO(&tbl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    FD_SET(fd, &tbl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    while(1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        if (select(/*ignored*/fd+1, &tbl, 0, 0, &t) <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
        if (recvfrom(fd, buf, 1, MSG_PEEK,
23015
73b21ab36615 8034174: Remove use of JVM_* functions from java.net code
chegar
parents: 23010
diff changeset
    58
                         (struct sockaddr *)&rmtaddr, &addrlen) != SOCKET_ERROR) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
        if (WSAGetLastError() != WSAECONNRESET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
            /* some other error - we don't care here */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        recvfrom(fd, buf, 1, 0,  (struct sockaddr *)&rmtaddr, &addrlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        got_icmp = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    return got_icmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * Class:     java_net_DualStackPlainDatagramSocketImpl
23023
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    75
 * Method:    initIDs
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    76
 * Signature: ()V
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    77
 */
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    78
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_initIDs
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    79
  (JNIEnv *env, jclass clazz)
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    80
{
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    81
    initInetAddressIDs(env);
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    82
}
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    83
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    84
/*
c1aebf9d16a9 8035653: InetAddress.getLocalHost crash
michaelm
parents: 23015
diff changeset
    85
 * Class:     java_net_DualStackPlainDatagramSocketImpl
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * Method:    socketCreate
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * Signature: (Z)I
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketCreate
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
  (JNIEnv *env, jclass clazz, jboolean v6Only /*unused*/) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    int fd, rv, opt=0, t=TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    DWORD x1, x2; /* ignored result codes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    fd = (int) socket(AF_INET6, SOCK_DGRAM, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    if (fd == INVALID_SOCKET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    if (rv == SOCKET_ERROR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
16054
a7cdb40ea8e8 8008804: file descriptor leak in src/windows/native/java/net/DualStackPlainSocketImpl.c
jzavgren
parents: 14342
diff changeset
   103
        closesocket(fd);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    NET_SetSockOpt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&t, sizeof(BOOL));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    /* SIO_UDP_CONNRESET fixes a "bug" introduced in Windows 2000, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * returns connection reset errors on unconnected UDP sockets (as well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * as connected sockets). The solution is to only enable this feature
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * when the socket is connected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    t = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    WSAIoctl(fd ,SIO_UDP_CONNRESET ,&t ,sizeof(t) ,&x1 ,sizeof(x1) ,&x2 ,0 ,0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    return fd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * Method:    socketBind
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 * Signature: (ILjava/net/InetAddress;I)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketBind
18192
fa6bd0992104 7170730: Improve Windows network stack support.
khazra
parents: 16054
diff changeset
   127
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port, jboolean exclBind) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    int rv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    int sa_len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                                 &sa_len, JNI_TRUE) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    }
18192
fa6bd0992104 7170730: Improve Windows network stack support.
khazra
parents: 16054
diff changeset
   136
    rv = NET_WinBind(fd, (struct sockaddr *)&sa, sa_len, exclBind);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    if (rv == SOCKET_ERROR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        if (WSAGetLastError() == WSAEACCES) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            WSASetLastError(WSAEADDRINUSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        NET_ThrowNew(env, WSAGetLastError(), "Cannot bind");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 * Method:    socketConnect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 * Signature: (ILjava/net/InetAddress;I)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketConnect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
  (JNIEnv *env, jclass clazz, jint fd, jobject iaObj, jint port) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    int rv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    int sa_len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    DWORD x1, x2; /* ignored result codes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    int t = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                                   &sa_len, JNI_TRUE) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    rv = connect(fd, (struct sockaddr *)&sa, sa_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    if (rv == SOCKET_ERROR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        NET_ThrowNew(env, WSAGetLastError(), "connect");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    /* see comment in socketCreate */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
 * Method:    socketDisconnect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
 * Signature: (I)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketDisconnect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
  (JNIEnv *env, jclass clazz, jint fd ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    int sa_len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    DWORD x1, x2; /* ignored result codes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    int t = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    memset(&sa, 0, sa_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    connect(fd, (struct sockaddr *)&sa, sa_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    /* see comment in socketCreate */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    WSAIoctl(fd, SIO_UDP_CONNRESET, &t, sizeof(t), &x1, sizeof(x1), &x2, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
 * Method:    socketClose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
 * Signature: (I)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketClose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
  (JNIEnv *env, jclass clazz , jint fd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    NET_SocketClose(fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
 * Method:    socketLocalPort
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
 * Signature: (I)I
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalPort
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
  (JNIEnv *env, jclass clazz, jint fd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    int len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
23015
73b21ab36615 8034174: Remove use of JVM_* functions from java.net code
chegar
parents: 23010
diff changeset
   215
        NET_ThrowNew(env, WSAGetLastError(), "getsockname");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    return (int) ntohs((u_short)GET_PORT(&sa));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
 * Method:    socketLocalAddress
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
 * Signature: (I)Ljava/lang/Object;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
JNIEXPORT jobject JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketLocalAddress
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
  (JNIEnv *env , jclass clazz, jint fd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    int len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    jobject iaObj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    int port;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    if (getsockname(fd, (struct sockaddr *)&sa, &len) == SOCKET_ERROR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    return iaObj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
 * Method:    socketReceiveOrPeekData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
 * Signature: (ILjava/net/DatagramPacket;IZZ)I
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketReceiveOrPeekData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
  (JNIEnv *env, jclass clazz, jint fd, jobject dpObj,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
   jint timeout, jboolean connected, jboolean peek) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    int sa_len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    int port, rv, flags=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    char BUF[MAX_BUFFER_LEN];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    char *fullPacket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    BOOL retry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    jlong prevTime = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    jint packetBufferOffset, packetBufferLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    jbyteArray packetBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    /* if we are only peeking. Called from peekData */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    if (peek) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        flags = MSG_PEEK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID);
17925
e8d88b57f82e 8008972: Memory leak: Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0 [parfait]
jzavgren
parents: 16054
diff changeset
   269
    /* Note: the buffer needn't be greater than 65,536 (0xFFFF)
e8d88b57f82e 8008972: Memory leak: Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0 [parfait]
jzavgren
parents: 16054
diff changeset
   270
    * the max size of an IP packet. Anything bigger is truncated anyway.
e8d88b57f82e 8008972: Memory leak: Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0 [parfait]
jzavgren
parents: 16054
diff changeset
   271
    */
e8d88b57f82e 8008972: Memory leak: Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0 [parfait]
jzavgren
parents: 16054
diff changeset
   272
    if (packetBufferLen > MAX_PACKET_LEN) {
e8d88b57f82e 8008972: Memory leak: Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0 [parfait]
jzavgren
parents: 16054
diff changeset
   273
        packetBufferLen = MAX_PACKET_LEN;
e8d88b57f82e 8008972: Memory leak: Java_java_net_TwoStacksPlainDatagramSocketImpl_receive0 [parfait]
jzavgren
parents: 16054
diff changeset
   274
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    if (packetBufferLen > MAX_BUFFER_LEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        fullPacket = (char *)malloc(packetBufferLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (!fullPacket) {
13245
7ab3ef5b9520 7181353: Update error message to distinguish native OOM and java OOM in net
zhouyx
parents: 5506
diff changeset
   279
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        fullPacket = &(BUF[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        retry = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        if (timeout) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            if (prevTime == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                prevTime = JVM_CurrentTimeMillis(env, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            rv = NET_Timeout(fd, timeout);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            if (rv <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                if (rv == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                    JNU_ThrowByName(env,JNU_JAVANETPKG "SocketTimeoutException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                                    "Receive timed out");
23015
73b21ab36615 8034174: Remove use of JVM_* functions from java.net code
chegar
parents: 23010
diff changeset
   298
                } else if (rv == -1) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                                    "Socket closed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                if (packetBufferLen > MAX_BUFFER_LEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                    free(fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        /* receive the packet */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        rv = recvfrom(fd, fullPacket, packetBufferLen, flags,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                    (struct sockaddr *)&sa, &sa_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        if (rv == SOCKET_ERROR && (WSAGetLastError() == WSAECONNRESET)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            /* An icmp port unreachable - we must receive this as Windows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
             * does not reset the state of the socket until this has been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
             * received.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            purgeOutstandingICMP(env, fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            if (connected) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                                "ICMP Port Unreachable");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                if (packetBufferLen > MAX_BUFFER_LEN)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                    free(fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            } else if (timeout) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                /* Adjust timeout */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                jlong newTime = JVM_CurrentTimeMillis(env, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                timeout -= (jint)(newTime - prevTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                if (timeout <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                                    "Receive timed out");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                    if (packetBufferLen > MAX_BUFFER_LEN)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                        free(fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                prevTime = newTime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            retry = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    } while (retry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    port = (int) ntohs ((u_short) GET_PORT((SOCKETADDRESS *)&sa));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    /* truncate the data if the packet's length is too small */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    if (rv > packetBufferLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        rv = packetBufferLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    if (rv < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        if (WSAGetLastError() == WSAEMSGSIZE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            /* it is because the buffer is too small. It's UDP, it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
             * unreliable, it's all good. discard the rest of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
             * data..
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            rv = packetBufferLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            /* failure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            (*env)->SetIntField(env, dpObj, dp_lengthID, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    if (rv == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    } else if (rv == -2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                        "operation interrupted");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    } else if (rv < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        NET_ThrowCurrent(env, "Datagram receive failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        jobject packetAddress;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
         * Check if there is an InetAddress already associated with this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
         * packet. If so, we check if it is the same source address. We
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
         * can't update any existing InetAddress because it is immutable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        packetAddress = (*env)->GetObjectField(env, dpObj, dp_addressID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        if (packetAddress != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&sa,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                                               packetAddress)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                /* force a new InetAddress to be created */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                packetAddress = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        if (packetAddress == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                                                      &port);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            /* stuff the new Inetaddress into the packet */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            (*env)->SetObjectField(env, dpObj, dp_addressID, packetAddress);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        /* populate the packet */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, rv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                                   (jbyte *)fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        (*env)->SetIntField(env, dpObj, dp_portID, port);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        (*env)->SetIntField(env, dpObj, dp_lengthID, rv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    if (packetBufferLen > MAX_BUFFER_LEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        free(fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    return port;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
 * Method:    socketSend
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
 * Signature: (I[BIILjava/net/InetAddress;IZ)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSend
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
  (JNIEnv *env, jclass clazz, jint fd, jbyteArray data, jint offset, jint length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     jobject iaObj, jint port, jboolean connected) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    SOCKETADDRESS sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    int sa_len = sizeof(sa);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    SOCKETADDRESS *sap = &sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    char BUF[MAX_BUFFER_LEN];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    char *fullPacket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    int rv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    if (connected) {
23015
73b21ab36615 8034174: Remove use of JVM_* functions from java.net code
chegar
parents: 23010
diff changeset
   420
        sap = 0; /* arg to sendto () null in this case */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        sa_len = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&sa,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                                       &sa_len, JNI_TRUE) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    if (length > MAX_BUFFER_LEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        /* Note: the buffer needn't be greater than 65,536 (0xFFFF)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
         * the max size of an IP packet. Anything bigger is truncated anyway.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        if (length > MAX_PACKET_LEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            length = MAX_PACKET_LEN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        fullPacket = (char *)malloc(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        if (!fullPacket) {
13245
7ab3ef5b9520 7181353: Update error message to distinguish native OOM and java OOM in net
zhouyx
parents: 5506
diff changeset
   438
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        fullPacket = &(BUF[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    (*env)->GetByteArrayRegion(env, data, offset, length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                               (jbyte *)fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    rv = sendto(fd, fullPacket, length, 0, (struct sockaddr *)sap, sa_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    if (rv == SOCKET_ERROR) {
23015
73b21ab36615 8034174: Remove use of JVM_* functions from java.net code
chegar
parents: 23010
diff changeset
   449
        if (rv == -1) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            NET_ThrowNew(env, WSAGetLastError(), "Datagram send failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    if (length > MAX_BUFFER_LEN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        free(fullPacket);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
 * Method:    socketSetIntOption
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
 * Signature: (III)V
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketSetIntOption
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
  (JNIEnv *env, jclass clazz, jint fd , jint cmd, jint value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    int level, opt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                                     "Invalid option");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    if (NET_SetSockOpt(fd, level, opt, (char *)&value, sizeof(value)) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
 * Class:     java_net_DualStackPlainDatagramSocketImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
 * Method:    socketGetIntOption
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
 * Signature: (II)I
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketGetIntOption
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
  (JNIEnv *env, jclass clazz, jint fd, jint cmd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    int level, opt, result=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    int result_len = sizeof(result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                                     "Invalid option");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    if (NET_GetSockOpt(fd, level, opt, (void *)&result, &result_len) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
}