~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
 
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
4
 *
 
5
 * This code is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU General Public License version 2 only, as
 
7
 * published by the Free Software Foundation.  Oracle designates this
 
8
 * particular file as subject to the "Classpath" exception as provided
 
9
 * by Oracle in the LICENSE file that accompanied this code.
 
10
 *
 
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
 
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
14
 * version 2 for more details (a copy is included in the LICENSE file that
 
15
 * accompanied this code).
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License version
 
18
 * 2 along with this work; if not, write to the Free Software Foundation,
 
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 *
 
21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 
22
 * or visit www.oracle.com if you need additional information or have any
 
23
 * questions.
 
24
 */
 
25
package java.net;
 
26
 
 
27
import java.io.IOException;
 
28
import java.io.FileDescriptor;
 
29
 
 
30
/**
 
31
 * This class defines the plain SocketImpl that is used on Windows platforms
 
32
 * greater or equal to Windows Vista. These platforms have a dual
 
33
 * layer TCP/IP stack and can handle both IPv4 and IPV6 through a
 
34
 * single file descriptor.
 
35
 *
 
36
 * @author Chris Hegarty
 
37
 * @author Jeroen Frijters
 
38
 */
 
39
 
 
40
class DualStackPlainSocketImpl extends AbstractPlainSocketImpl
 
41
{
 
42
    public DualStackPlainSocketImpl() {}
 
43
 
 
44
    public DualStackPlainSocketImpl(FileDescriptor fd) {
 
45
        this.fd = fd;
 
46
    }
 
47
 
 
48
    void socketCreate(boolean stream) throws IOException {
 
49
        if (fd == null)
 
50
            throw new SocketException("Socket closed");
 
51
 
 
52
        cli.System.Net.Sockets.Socket newfd = socket0(stream, false /*v6 Only*/);
 
53
 
 
54
        fd.setSocket(newfd);
 
55
    }
 
56
 
 
57
    void socketConnect(InetAddress address, int port, int timeout)
 
58
        throws IOException {
 
59
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
60
 
 
61
        if (address == null)
 
62
            throw new NullPointerException("inet address argument is null.");
 
63
 
 
64
        int connectResult;
 
65
        if (timeout <= 0) {
 
66
            connectResult = connect0(nativefd, address, port);
 
67
        } else {
 
68
            configureBlocking(nativefd, false);
 
69
            try {
 
70
                connectResult = connect0(nativefd, address, port);
 
71
                if (connectResult == WOULDBLOCK) {
 
72
                    waitForConnect(nativefd, timeout);
 
73
                }
 
74
            } finally {
 
75
                configureBlocking(nativefd, true);
 
76
            }
 
77
        }
 
78
        /*
 
79
         * We need to set the local port field. If bind was called
 
80
         * previous to the connect (by the client) then localport field
 
81
         * will already be set.
 
82
         */
 
83
        if (localport == 0)
 
84
            localport = localPort0(nativefd);
 
85
    }
 
86
 
 
87
    void socketBind(InetAddress address, int port) throws IOException {
 
88
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
89
 
 
90
        if (address == null)
 
91
            throw new NullPointerException("inet address argument is null.");
 
92
 
 
93
        bind0(nativefd, address, port);
 
94
        if (port == 0) {
 
95
            localport = localPort0(nativefd);
 
96
        } else {
 
97
            localport = port;
 
98
        }
 
99
 
 
100
        this.address = address;
 
101
    }
 
102
 
 
103
    void socketListen(int backlog) throws IOException {
 
104
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
105
 
 
106
        listen0(nativefd, backlog);
 
107
    }
 
108
 
 
109
    void socketAccept(SocketImpl s) throws IOException {
 
110
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
111
 
 
112
        if (s == null)
 
113
            throw new NullPointerException("socket is null");
 
114
 
 
115
        cli.System.Net.Sockets.Socket newfd = null;
 
116
        InetSocketAddress[] isaa = new InetSocketAddress[1];
 
117
        if (timeout <= 0) {
 
118
            newfd = accept0(nativefd, isaa);
 
119
        } else {
 
120
            configureBlocking(nativefd, false);
 
121
            try {
 
122
                waitForNewConnection(nativefd, timeout);
 
123
                newfd = accept0(nativefd, isaa);
 
124
                if (newfd != null) {
 
125
                    configureBlocking(newfd, true);
 
126
                }
 
127
            } finally {
 
128
                configureBlocking(nativefd, true);
 
129
            }
 
130
        }
 
131
        /* Update (SocketImpl)s' fd */
 
132
        s.fd.setSocket(newfd);
 
133
        /* Update socketImpls remote port, address and localport */
 
134
        InetSocketAddress isa = isaa[0];
 
135
        s.port = isa.getPort();
 
136
        s.address = isa.getAddress();
 
137
        s.localport = localport;
 
138
    }
 
139
 
 
140
    int socketAvailable() throws IOException {
 
141
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
142
        return available0(nativefd);
 
143
    }
 
144
 
 
145
    void socketClose0(boolean useDeferredClose/*unused*/) throws IOException {
 
146
        if (fd == null)
 
147
            throw new SocketException("Socket closed");
 
148
 
 
149
        if (!fd.valid())
 
150
            return;
 
151
 
 
152
        close0(fd.getSocket());
 
153
        fd.setSocket(null);
 
154
    }
 
155
 
 
156
    void socketShutdown(int howto) throws IOException {
 
157
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
158
        shutdown0(nativefd, howto);
 
159
    }
 
160
 
 
161
    void socketSetOption(int opt, boolean on, Object value)
 
162
        throws SocketException {
 
163
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
164
 
 
165
        if (opt == SO_TIMEOUT) {  // timeout implemented through select.
 
166
            return;
 
167
        }
 
168
 
 
169
        int optionValue = 0;
 
170
 
 
171
        switch(opt) {
 
172
            case TCP_NODELAY :
 
173
            case SO_OOBINLINE :
 
174
            case SO_KEEPALIVE :
 
175
            case SO_REUSEADDR :
 
176
                optionValue = on ? 1 : 0;
 
177
                break;
 
178
            case SO_SNDBUF :
 
179
            case SO_RCVBUF :
 
180
            case IP_TOS :
 
181
                optionValue = ((Integer)value).intValue();
 
182
                break;
 
183
            case SO_LINGER :
 
184
                if (on) {
 
185
                    optionValue =  ((Integer)value).intValue();
 
186
                } else {
 
187
                    optionValue = -1;
 
188
                }
 
189
                break;
 
190
            default :/* shouldn't get here */
 
191
                throw new SocketException("Option not supported");
 
192
        }
 
193
 
 
194
        setIntOption(nativefd, opt, optionValue);
 
195
    }
 
196
 
 
197
    int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
 
198
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
199
 
 
200
        // SO_BINDADDR is not a socket option.
 
201
        if (opt == SO_BINDADDR) {
 
202
            localAddress(nativefd, (InetAddressContainer)iaContainerObj);
 
203
            return 0;  // return value doesn't matter.
 
204
        }
 
205
 
 
206
        int value = getIntOption(nativefd, opt);
 
207
 
 
208
        switch (opt) {
 
209
            case TCP_NODELAY :
 
210
            case SO_OOBINLINE :
 
211
            case SO_KEEPALIVE :
 
212
            case SO_REUSEADDR :
 
213
                return (value == 0) ? -1 : 1;
 
214
        }
 
215
        return value;
 
216
    }
 
217
 
 
218
    void socketSendUrgentData(int data) throws IOException {
 
219
        cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD();
 
220
        sendOOB(nativefd, data);
 
221
    }
 
222
 
 
223
    private cli.System.Net.Sockets.Socket checkAndReturnNativeFD() throws SocketException {
 
224
        if (fd == null || !fd.valid())
 
225
            throw new SocketException("Socket closed");
 
226
 
 
227
        return fd.getSocket();
 
228
    }
 
229
 
 
230
    static final int WOULDBLOCK = -2;       // Nothing available (non-blocking)
 
231
 
 
232
    /* Native methods */
 
233
 
 
234
    static cli.System.Net.Sockets.Socket socket0(boolean stream, boolean v6Only) throws IOException {
 
235
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
236
        cli.System.Net.Sockets.Socket ret = DualStackPlainSocketImpl_c.socket0(env, stream, v6Only);
 
237
        env.ThrowPendingException();
 
238
        return ret;
 
239
    }
 
240
 
 
241
    static void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport)
 
242
        throws IOException {
 
243
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
244
        DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport);
 
245
        env.ThrowPendingException();
 
246
    }
 
247
 
 
248
    static int connect0(cli.System.Net.Sockets.Socket fd, InetAddress remote, int remotePort)
 
249
        throws IOException {
 
250
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
251
        int ret = DualStackPlainSocketImpl_c.connect0(env, fd, remote, remotePort);
 
252
        env.ThrowPendingException();
 
253
        return ret;
 
254
    }
 
255
 
 
256
    static void waitForConnect(cli.System.Net.Sockets.Socket fd, int timeout) throws IOException {
 
257
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
258
        DualStackPlainSocketImpl_c.waitForConnect(env, fd, timeout);
 
259
        env.ThrowPendingException();
 
260
    }
 
261
 
 
262
    static int localPort0(cli.System.Net.Sockets.Socket fd) throws IOException {
 
263
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
264
        int ret = DualStackPlainSocketImpl_c.localPort0(env, fd);
 
265
        env.ThrowPendingException();
 
266
        return ret;
 
267
    }
 
268
 
 
269
    static void localAddress(cli.System.Net.Sockets.Socket fd, InetAddressContainer in) throws SocketException {
 
270
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
271
        DualStackPlainSocketImpl_c.localAddress(env, fd, in);
 
272
        env.ThrowPendingException();
 
273
    }
 
274
 
 
275
    static void listen0(cli.System.Net.Sockets.Socket fd, int backlog) throws IOException {
 
276
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
277
        DualStackPlainSocketImpl_c.listen0(env, fd, backlog);
 
278
        env.ThrowPendingException();
 
279
    }
 
280
 
 
281
    static cli.System.Net.Sockets.Socket accept0(cli.System.Net.Sockets.Socket fd, InetSocketAddress[] isaa) throws IOException {
 
282
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
283
        cli.System.Net.Sockets.Socket ret = DualStackPlainSocketImpl_c.accept0(env, fd, isaa);
 
284
        env.ThrowPendingException();
 
285
        return ret;
 
286
    }
 
287
 
 
288
    static void waitForNewConnection(cli.System.Net.Sockets.Socket fd, int timeout) throws IOException {
 
289
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
290
        DualStackPlainSocketImpl_c.waitForNewConnection(env, fd, timeout);
 
291
        env.ThrowPendingException();
 
292
    }
 
293
 
 
294
    static int available0(cli.System.Net.Sockets.Socket fd) throws IOException {
 
295
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
296
        int ret = DualStackPlainSocketImpl_c.available0(env, fd);
 
297
        env.ThrowPendingException();
 
298
        return ret;
 
299
    }
 
300
 
 
301
    static void close0(cli.System.Net.Sockets.Socket fd) throws IOException {
 
302
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
303
        DualStackPlainSocketImpl_c.close0(env, fd);
 
304
        env.ThrowPendingException();
 
305
    }
 
306
 
 
307
    static void shutdown0(cli.System.Net.Sockets.Socket fd, int howto) throws IOException {
 
308
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
309
        DualStackPlainSocketImpl_c.shutdown0(env, fd, howto);
 
310
        env.ThrowPendingException();
 
311
    }
 
312
 
 
313
    static void setIntOption(cli.System.Net.Sockets.Socket fd, int cmd, int optionValue) throws SocketException {
 
314
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
315
        DualStackPlainSocketImpl_c.setIntOption(env, fd, cmd, optionValue);
 
316
        env.ThrowPendingException();
 
317
    }
 
318
 
 
319
    static int getIntOption(cli.System.Net.Sockets.Socket fd, int cmd) throws SocketException {
 
320
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
321
        int ret = DualStackPlainSocketImpl_c.getIntOption(env, fd, cmd);
 
322
        env.ThrowPendingException();
 
323
        return ret;
 
324
    }
 
325
 
 
326
    static void sendOOB(cli.System.Net.Sockets.Socket fd, int data) throws IOException {
 
327
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
328
        DualStackPlainSocketImpl_c.sendOOB(env, fd, data);
 
329
        env.ThrowPendingException();
 
330
    }
 
331
 
 
332
    static void configureBlocking(cli.System.Net.Sockets.Socket fd, boolean blocking) throws IOException {
 
333
        ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv();
 
334
        DualStackPlainSocketImpl_c.configureBlocking(env, fd, blocking);
 
335
        env.ThrowPendingException();
 
336
    }
 
337
}