001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Mikhail A. Markov
021: * @version $Revision: 1.1.2.2 $
022: */package org.apache.harmony.rmi.transport.tcp;
023:
024: import java.io.DataInputStream;
025: import java.io.DataOutputStream;
026: import java.io.IOException;
027: import java.net.Socket;
028: import java.rmi.RemoteException;
029: import java.rmi.UnmarshalException;
030: import java.rmi.server.UID;
031: import java.security.AccessController;
032:
033: import org.apache.harmony.rmi.common.GetLongPropAction;
034: import org.apache.harmony.rmi.common.RMILog;
035: import org.apache.harmony.rmi.common.RMIProperties;
036: import org.apache.harmony.rmi.internal.nls.Messages;
037: import org.apache.harmony.rmi.server.ServerConnection;
038: import org.apache.harmony.rmi.server.ServerConnectionManager;
039:
040: /**
041: * Tcp extension of ServerConnection.
042: *
043: * @author Mikhail A. Markov
044: * @version $Revision: 1.1.2.2 $
045: */
046: public class TcpServerConnection extends ServerConnection {
047:
048: /** Log for logging tcp connections activity. */
049: protected static final RMILog tcpTransportLog = RMILog
050: .getTcpTransportLog();
051:
052: /*
053: * The time used as an idle timeout for incoming connections (in ms).
054: * Default value is 2 * 3600 * 1000 ms (2 hours).
055: */
056: private static int readTimeout = ((Long) AccessController
057: .doPrivileged(new GetLongPropAction(
058: RMIProperties.READTIMEOUT_PROP, 2 * 3600 * 1000)))
059: .intValue();
060:
061: /**
062: * Constructs TcpServerConnection working through socket specified.
063: *
064: * @param s Socket connected to the client
065: * @param mgr ConnectionManager managing this connection
066: *
067: * @throws IOException if an I/O error occurred during getting
068: * input/output streams from specified socket
069: */
070: public TcpServerConnection(Socket s, ServerConnectionManager mgr)
071: throws IOException {
072: super (s, mgr);
073: s.setSoTimeout(readTimeout);
074: }
075:
076: /**
077: * @see ServerConnection.clientProtocolAck()
078: */
079: protected int clientProtocolAck() throws IOException {
080: byte data;
081: DataInputStream din = new DataInputStream(in);
082:
083: try {
084: // read RMI header
085: int header = din.readInt();
086:
087: if (header != RMI_HEADER) {
088: // rmi.82=Unknown header: {0}
089: throw new UnmarshalException(Messages.getString(
090: "rmi.82", header)); //$NON-NLS-1$
091: }
092:
093: // read RMI protocol version
094: short ver = din.readShort();
095:
096: if (ver != PROTOCOL_VER) {
097: // rmi.83=Unknown RMI protocol version: {0}
098: throw new UnmarshalException(Messages.getString(
099: "rmi.83", ver)); //$NON-NLS-1$
100: }
101: } catch (IOException ioe) {
102: // rmi.84=Unable to read RMI protocol header
103: throw new UnmarshalException(Messages.getString("rmi.84"), //$NON-NLS-1$
104: ioe);
105: }
106:
107: if (tcpTransportLog.isLoggable(RMILog.VERBOSE)) {
108: // rmi.85=Using protocol version {0}
109: tcpTransportLog.log(RMILog.VERBOSE, Messages.getString(
110: "rmi.85", //$NON-NLS-1$
111: PROTOCOL_VER));
112: }
113: DataOutputStream dout = new DataOutputStream(out);
114:
115: // read protocol type
116: if (din.readByte() == STREAM_PROTOCOL) {
117: if (tcpTransportLog.isLoggable(RMILog.VERBOSE)) {
118: // rmi.90=Using stream RMI protocol
119: tcpTransportLog.log(RMILog.VERBOSE, Messages
120: .getString("rmi.90")); //$NON-NLS-1$
121: }
122: } else {
123: dout.writeByte(PROTOCOL_NOT_SUPPORTED);
124: dout.flush();
125: return -1;
126: }
127:
128: // send ack msg
129: dout.writeByte(PROTOCOL_ACK);
130:
131: // send client's host and port
132: String host = s.getInetAddress().getHostAddress();
133: int port = s.getPort();
134: dout.writeUTF(host);
135: dout.writeInt(port);
136: dout.flush();
137:
138: if (tcpTransportLog.isLoggable(RMILog.VERBOSE)) {
139: // rmi.log.136=Server is seeing client as {0}:{1}
140: tcpTransportLog.log(RMILog.VERBOSE, Messages.getString(
141: "rmi.log.136", host, port)); //$NON-NLS-1$ //$NON-NLS-2$
142: }
143:
144: // read host and port
145: din.readUTF();
146: din.readInt();
147:
148: // protocol is agreed
149: return STREAM_PROTOCOL;
150: }
151:
152: /**
153: * @see ServerConnection.waitCallMsg()
154: */
155: protected int waitCallMsg() throws IOException {
156: int data;
157:
158: while (true) {
159: try {
160: data = in.read();
161: } catch (IOException ioe) {
162: data = -1;
163: }
164:
165: if (data == -1) {
166: if (tcpTransportLog.isLoggable(RMILog.BRIEF)) {
167: // rmi.log.123=Connection [{0}] is closed
168: tcpTransportLog.log(RMILog.BRIEF, Messages
169: .getString("rmi.log.123", toString())); //$NON-NLS-1$ //$NON-NLS-2$
170: }
171: return -1;
172: }
173: DataOutputStream dout = new DataOutputStream(out);
174:
175: if (data == PING_MSG) {
176: if (tcpTransportLog.isLoggable(RMILog.VERBOSE)) {
177: // rmi.log.124=Got ping request
178: tcpTransportLog.log(RMILog.VERBOSE, Messages
179: .getString("rmi.log.124")); //$NON-NLS-1$
180: }
181:
182: // send ping ack
183: dout.writeByte(PING_ACK);
184: dout.flush();
185: } else if (data == DGCACK_MSG) {
186: if (tcpTransportLog.isLoggable(RMILog.VERBOSE)) {
187: // rmi.log.125=Got DGC ack request
188: tcpTransportLog.log(RMILog.VERBOSE, Messages
189: .getString("rmi.log.125")); //$NON-NLS-1$
190: }
191: dgcUnregisterUID(UID.read(new DataInputStream(in)));
192: } else if (data == CALL_MSG) {
193: if (tcpTransportLog.isLoggable(RMILog.VERBOSE)) {
194: // rmi.log.126=Got call request
195: tcpTransportLog.log(RMILog.VERBOSE, Messages
196: .getString("rmi.log.126")); //$NON-NLS-1$
197: }
198: return data;
199: } else {
200: if (tcpTransportLog.isLoggable(RMILog.BRIEF)) {
201: // rmi.log.127=Unknown request got: {0}
202: tcpTransportLog.log(RMILog.BRIEF, Messages
203: .getString("rmi.log.127", data)); //$NON-NLS-1$
204: }
205: // rmi.91=Unknown message got: {0}
206: throw new RemoteException(Messages.getString(
207: "rmi.91", data)); //$NON-NLS-1$
208: }
209: }
210: }
211:
212: /**
213: * Returns string representation of this connection.
214: *
215: * @return string representation of this connection
216: */
217: public String toString() {
218: return "TcpServerConnection: remote endpoint:" + ep; //$NON-NLS-1$
219: }
220: }
|