blob: 770871e7b6b2db97dd74d67c15395bf942963995 [file] [log] [blame]
/*
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
* Copyright 1997 The Open Group Research Institute. All rights reserved.
*/
package sun.security.krb5.internal;
import java.io.*;
import java.net.*;
public class TCPClient {
private Socket tcpSocket;
private BufferedOutputStream out;
private BufferedInputStream in;
public TCPClient(String hostname, int port) throws IOException {
tcpSocket = new Socket(hostname, port);
out = new BufferedOutputStream(tcpSocket.getOutputStream());
in = new BufferedInputStream(tcpSocket.getInputStream());
}
public void send(byte[] data) throws IOException {
byte[] lenField = new byte[4];
intToNetworkByteOrder(data.length, lenField, 0, 4);
out.write(lenField);
out.write(data);
out.flush();
}
public byte[] receive() throws IOException {
byte[] lenField = new byte[4];
int count = readFully(lenField, 4);
if (count != 4) {
if (Krb5.DEBUG) {
System.out.println(
">>>DEBUG: TCPClient could not read length field");
}
return null;
}
int len = networkByteOrderToInt(lenField, 0, 4);
if (Krb5.DEBUG) {
System.out.println(
">>>DEBUG: TCPClient reading " + len + " bytes");
}
if (len <= 0) {
if (Krb5.DEBUG) {
System.out.println(
">>>DEBUG: TCPClient zero or negative length field: "+len);
}
return null;
}
byte data[] = new byte[len];
count = readFully(data, len);
if (count != len) {
if (Krb5.DEBUG) {
System.out.println(
">>>DEBUG: TCPClient could not read complete packet (" +
len + "/" + count + ")");
}
return null;
} else {
return data;
}
}
public void close() throws IOException {
tcpSocket.close();
}
/**
* Read requested number of bytes before returning.
* @return The number of bytes actually read; -1 if none read
*/
private int readFully(byte[] inBuf, int total) throws IOException {
int count, pos = 0;
while (total > 0) {
count = in.read(inBuf, pos, total);
if (count == -1) {
return (pos == 0? -1 : pos);
}
pos += count;
total -= count;
}
return pos;
}
/**
* Returns the integer represented by 4 bytes in network byte order.
*/
private static final int networkByteOrderToInt(byte[] buf, int start,
int count) {
if (count > 4) {
throw new IllegalArgumentException(
"Cannot handle more than 4 bytes");
}
int answer = 0;
for (int i = 0; i < count; i++) {
answer <<= 8;
answer |= ((int)buf[start+i] & 0xff);
}
return answer;
}
/**
* Encodes an integer into 4 bytes in network byte order in the buffer
* supplied.
*/
private static final void intToNetworkByteOrder(int num, byte[] buf,
int start, int count) {
if (count > 4) {
throw new IllegalArgumentException(
"Cannot handle more than 4 bytes");
}
for (int i = count-1; i >= 0; i--) {
buf[start+i] = (byte)(num & 0xff);
num >>>= 8;
}
}
}