1 /******************************************************************************* 2 * Copyright (c) 2000, 2016 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Google Inc - add support for accepting multiple connections 14 *******************************************************************************/ 15 package org.eclipse.jdi.internal.connect; 16 17 import java.io.DataInputStream; 18 import java.io.IOException; 19 import java.io.InputStream; 20 import java.io.OutputStream; 21 import java.net.Socket; 22 23 import com.sun.jdi.connect.spi.ClosedConnectionException; 24 import com.sun.jdi.connect.spi.Connection; 25 26 public class SocketConnection extends Connection { 27 28 // for attaching connector 29 private Socket fSocket; 30 31 private InputStream fInput; 32 33 private OutputStream fOutput; 34 SocketConnection(Socket socket, InputStream in, OutputStream out)35 SocketConnection(Socket socket, InputStream in, OutputStream out) { 36 fSocket = socket; 37 fInput = in; 38 fOutput = out; 39 } 40 41 /* 42 * (non-Javadoc) 43 * 44 * @see com.sun.jdi.connect.spi.Connection#close() 45 */ 46 @Override close()47 public synchronized void close() throws IOException { 48 if (fSocket == null) 49 return; 50 51 fSocket.close(); 52 fSocket = null; 53 } 54 55 /* 56 * (non-Javadoc) 57 * 58 * @see com.sun.jdi.connect.spi.Connection#isOpen() 59 */ 60 @Override isOpen()61 public synchronized boolean isOpen() { 62 return fSocket != null; 63 } 64 65 /* 66 * (non-Javadoc) 67 * 68 * @see com.sun.jdi.connect.spi.Connection#readPacket() 69 */ 70 @Override readPacket()71 public byte[] readPacket() throws IOException { 72 DataInputStream stream; 73 synchronized (this) { 74 if (!isOpen()) { 75 throw new ClosedConnectionException(); 76 } 77 stream = new DataInputStream(fInput); 78 } 79 synchronized (stream) { 80 int packetLength = 0; 81 try { 82 packetLength = stream.readInt(); 83 } catch (IOException e) { 84 throw new ClosedConnectionException(); 85 } 86 87 if (packetLength < 11) { 88 throw new IOException("JDWP Packet under 11 bytes"); //$NON-NLS-1$ 89 } 90 91 byte[] packet = new byte[packetLength]; 92 packet[0] = (byte) ((packetLength >>> 24) & 0xFF); 93 packet[1] = (byte) ((packetLength >>> 16) & 0xFF); 94 packet[2] = (byte) ((packetLength >>> 8) & 0xFF); 95 packet[3] = (byte) ((packetLength >>> 0) & 0xFF); 96 97 stream.readFully(packet, 4, packetLength - 4); 98 return packet; 99 } 100 } 101 102 /* 103 * (non-Javadoc) 104 * 105 * @see com.sun.jdi.connect.spi.Connection#writePacket(byte[]) 106 */ 107 @Override writePacket(byte[] packet)108 public void writePacket(byte[] packet) throws IOException { 109 if (!isOpen()) { 110 throw new ClosedConnectionException(); 111 } 112 if (packet == null) { 113 throw new IllegalArgumentException( 114 "Invalid JDWP Packet, packet cannot be null"); //$NON-NLS-1$ 115 } 116 if (packet.length < 11) { 117 throw new IllegalArgumentException( 118 "Invalid JDWP Packet, must be at least 11 bytes. PacketSize:" + packet.length); //$NON-NLS-1$ 119 } 120 121 int packetSize = getPacketLength(packet); 122 if (packetSize < 11) { 123 throw new IllegalArgumentException( 124 "Invalid JDWP Packet, must be at least 11 bytes. PacketSize:" + packetSize); //$NON-NLS-1$ 125 } 126 127 if (packetSize > packet.length) { 128 throw new IllegalArgumentException( 129 "Invalid JDWP packet: Specified length is greater than actual length"); //$NON-NLS-1$ 130 } 131 132 OutputStream stream = null; 133 synchronized (this) { 134 if (!isOpen()) { 135 throw new ClosedConnectionException(); 136 } 137 stream = fOutput; 138 } 139 140 synchronized (stream) { 141 // packet.length can be > packetSize. Sending too much will cause 142 // errors on the other side 143 stream.write(packet, 0, packetSize); 144 } 145 } 146 getPacketLength(byte[] packet)147 private int getPacketLength(byte[] packet) { 148 int len = 0; 149 if (packet.length >= 4) { 150 len = (((packet[0] & 0xFF) << 24) + ((packet[1] & 0xFF) << 16) 151 + ((packet[2] & 0xFF) << 8) + ((packet[3] & 0xFF) << 0)); 152 } 153 return len; 154 } 155 } 156