blob: 03165d681969d9f58085670ccbc0e12e2674ce69 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2004 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26/*
27 */
28
29package sun.nio.ch;
30
31import java.io.IOException;
32import java.net.InetAddress;
33import java.net.InetSocketAddress;
34import java.nio.*;
35import java.nio.channels.*;
36import java.nio.channels.spi.*;
37import java.security.AccessController;
38import java.security.PrivilegedExceptionAction;
39import java.security.PrivilegedActionException;
40import java.util.Random;
41
42
43/**
44 * A simple Pipe implementation based on a socket connection.
45 */
46
47class PipeImpl
48 extends Pipe
49{
50
51 // Source and sink channels
52 private SourceChannel source;
53 private SinkChannel sink;
54
55 // Random object for handshake values
56 private static final Random rnd;
57
58 static {
59 Util.load();
60 byte[] someBytes = new byte[8];
61 boolean resultOK = IOUtil.randomBytes(someBytes);
62 if (resultOK) {
63 rnd = new Random(ByteBuffer.wrap(someBytes).getLong());
64 } else {
65 rnd = new Random();
66 }
67 }
68
69 private class Initializer
70 implements PrivilegedExceptionAction
71 {
72
73 private final SelectorProvider sp;
74
75 private Initializer(SelectorProvider sp) {
76 this.sp = sp;
77 }
78
79 public Object run() throws IOException {
80 ServerSocketChannel ssc = null;
81 SocketChannel sc1 = null;
82 SocketChannel sc2 = null;
83
84 try {
85 // loopback address
86 InetAddress lb = InetAddress.getByName("127.0.0.1");
87 assert(lb.isLoopbackAddress());
88
89 // bind ServerSocketChannel to a port on the loopback address
90 ssc = ServerSocketChannel.open();
91 ssc.socket().bind(new InetSocketAddress(lb, 0));
92
93 // Establish connection (assumes connections are eagerly
94 // accepted)
95 InetSocketAddress sa
96 = new InetSocketAddress(lb, ssc.socket().getLocalPort());
97 sc1 = SocketChannel.open(sa);
98
99 ByteBuffer bb = ByteBuffer.allocate(8);
100 long secret = rnd.nextLong();
101 bb.putLong(secret).flip();
102 sc1.write(bb);
103
104 // Get a connection and verify it is legitimate
105 for (;;) {
106 sc2 = ssc.accept();
107 bb.clear();
108 sc2.read(bb);
109 bb.rewind();
110 if (bb.getLong() == secret)
111 break;
112 sc2.close();
113 }
114
115 // Create source and sink channels
116 source = new SourceChannelImpl(sp, sc1);
117 sink = new SinkChannelImpl(sp, sc2);
118 } catch (IOException e) {
119 try {
120 if (sc1 != null)
121 sc1.close();
122 if (sc2 != null)
123 sc2.close();
124 } catch (IOException e2) { }
125 IOException x = new IOException("Unable to establish"
126 + " loopback connection");
127 x.initCause(e);
128 throw x;
129 } finally {
130 try {
131 if (ssc != null)
132 ssc.close();
133 } catch (IOException e2) { }
134 }
135 return null;
136 }
137 }
138
139 PipeImpl(final SelectorProvider sp) throws IOException {
140 try {
141 AccessController.doPrivileged(new Initializer(sp));
142 } catch (PrivilegedActionException x) {
143 throw (IOException)x.getCause();
144 }
145 }
146
147
148 public SourceChannel source() {
149 return source;
150 }
151
152 public SinkChannel sink() {
153 return sink;
154 }
155
156}