blob: 4ae41ab48a44383de3245fef865cf218aa2257aa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Google Inc - add support for accepting multiple connections
*******************************************************************************/
package org.eclipse.jdi.internal.connect;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import com.sun.jdi.connect.spi.ClosedConnectionException;
import com.sun.jdi.connect.spi.Connection;
public class SocketConnection extends Connection {
// for attaching connector
private Socket fSocket;
private InputStream fInput;
private OutputStream fOutput;
SocketConnection(Socket socket, InputStream in, OutputStream out) {
fSocket = socket;
fInput = in;
fOutput = out;
}
/*
* (non-Javadoc)
*
* @see com.sun.jdi.connect.spi.Connection#close()
*/
@Override
public synchronized void close() throws IOException {
if (fSocket == null)
return;
fSocket.close();
fSocket = null;
}
/*
* (non-Javadoc)
*
* @see com.sun.jdi.connect.spi.Connection#isOpen()
*/
@Override
public synchronized boolean isOpen() {
return fSocket != null;
}
/*
* (non-Javadoc)
*
* @see com.sun.jdi.connect.spi.Connection#readPacket()
*/
@Override
public byte[] readPacket() throws IOException {
DataInputStream stream;
synchronized (this) {
if (!isOpen()) {
throw new ClosedConnectionException();
}
stream = new DataInputStream(fInput);
}
synchronized (stream) {
int packetLength = 0;
try {
packetLength = stream.readInt();
} catch (IOException e) {
throw new ClosedConnectionException();
}
if (packetLength < 11) {
throw new IOException("JDWP Packet under 11 bytes"); //$NON-NLS-1$
}
byte[] packet = new byte[packetLength];
packet[0] = (byte) ((packetLength >>> 24) & 0xFF);
packet[1] = (byte) ((packetLength >>> 16) & 0xFF);
packet[2] = (byte) ((packetLength >>> 8) & 0xFF);
packet[3] = (byte) ((packetLength >>> 0) & 0xFF);
stream.readFully(packet, 4, packetLength - 4);
return packet;
}
}
/*
* (non-Javadoc)
*
* @see com.sun.jdi.connect.spi.Connection#writePacket(byte[])
*/
@Override
public void writePacket(byte[] packet) throws IOException {
if (!isOpen()) {
throw new ClosedConnectionException();
}
if (packet == null) {
throw new IllegalArgumentException(
"Invalid JDWP Packet, packet cannot be null"); //$NON-NLS-1$
}
if (packet.length < 11) {
throw new IllegalArgumentException(
"Invalid JDWP Packet, must be at least 11 bytes. PacketSize:" + packet.length); //$NON-NLS-1$
}
int packetSize = getPacketLength(packet);
if (packetSize < 11) {
throw new IllegalArgumentException(
"Invalid JDWP Packet, must be at least 11 bytes. PacketSize:" + packetSize); //$NON-NLS-1$
}
if (packetSize > packet.length) {
throw new IllegalArgumentException(
"Invalid JDWP packet: Specified length is greater than actual length"); //$NON-NLS-1$
}
OutputStream stream = null;
synchronized (this) {
if (!isOpen()) {
throw new ClosedConnectionException();
}
stream = fOutput;
}
synchronized (stream) {
// packet.length can be > packetSize. Sending too much will cause
// errors on the other side
stream.write(packet, 0, packetSize);
}
}
private int getPacketLength(byte[] packet) {
int len = 0;
if (packet.length >= 4) {
len = (((packet[0] & 0xFF) << 24) + ((packet[1] & 0xFF) << 16)
+ ((packet[2] & 0xFF) << 8) + ((packet[3] & 0xFF) << 0));
}
return len;
}
}