Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/krb5/internal/NetClient.java
38923 views
/*1* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26*27* (C) Copyright IBM Corp. 1999 All Rights Reserved.28* Copyright 1997 The Open Group Research Institute. All rights reserved.29*/3031package sun.security.krb5.internal;3233import sun.misc.IOUtils;3435import java.io.*;36import java.net.*;3738public abstract class NetClient implements AutoCloseable {39public static NetClient getInstance(String protocol, String hostname, int port,40int timeout) throws IOException {41if (protocol.equals("TCP")) {42return new TCPClient(hostname, port, timeout);43} else {44return new UDPClient(hostname, port, timeout);45}46}4748abstract public void send(byte[] data) throws IOException;49abstract public byte[] receive() throws IOException;50abstract public void close() throws IOException;51}5253class TCPClient extends NetClient {5455private Socket tcpSocket;56private BufferedOutputStream out;57private BufferedInputStream in;5859TCPClient(String hostname, int port, int timeout)60throws IOException {61tcpSocket = new Socket();62tcpSocket.connect(new InetSocketAddress(hostname, port), timeout);63out = new BufferedOutputStream(tcpSocket.getOutputStream());64in = new BufferedInputStream(tcpSocket.getInputStream());65tcpSocket.setSoTimeout(timeout);66}6768@Override69public void send(byte[] data) throws IOException {70byte[] lenField = new byte[4];71intToNetworkByteOrder(data.length, lenField, 0, 4);72out.write(lenField);7374out.write(data);75out.flush();76}7778@Override79public byte[] receive() throws IOException {80byte[] lenField = new byte[4];81int count = readFully(lenField, 4);8283if (count != 4) {84if (Krb5.DEBUG) {85System.out.println(86">>>DEBUG: TCPClient could not read length field");87}88return null;89}9091int len = networkByteOrderToInt(lenField, 0, 4);92if (Krb5.DEBUG) {93System.out.println(94">>>DEBUG: TCPClient reading " + len + " bytes");95}96if (len <= 0) {97if (Krb5.DEBUG) {98System.out.println(99">>>DEBUG: TCPClient zero or negative length field: "+len);100}101return null;102}103104try {105return IOUtils.readExactlyNBytes(in, len);106} catch (IOException ioe) {107if (Krb5.DEBUG) {108System.out.println(109">>>DEBUG: TCPClient could not read complete packet (" +110len + "/" + count + ")");111}112return null;113}114}115116@Override117public void close() throws IOException {118tcpSocket.close();119}120121/**122* Read requested number of bytes before returning.123* @return The number of bytes actually read; -1 if none read124*/125private int readFully(byte[] inBuf, int total) throws IOException {126int count, pos = 0;127128while (total > 0) {129count = in.read(inBuf, pos, total);130131if (count == -1) {132return (pos == 0? -1 : pos);133}134pos += count;135total -= count;136}137return pos;138}139140/**141* Returns the integer represented by 4 bytes in network byte order.142*/143private static int networkByteOrderToInt(byte[] buf, int start,144int count) {145if (count > 4) {146throw new IllegalArgumentException(147"Cannot handle more than 4 bytes");148}149150int answer = 0;151152for (int i = 0; i < count; i++) {153answer <<= 8;154answer |= ((int)buf[start+i] & 0xff);155}156return answer;157}158159/**160* Encodes an integer into 4 bytes in network byte order in the buffer161* supplied.162*/163private static void intToNetworkByteOrder(int num, byte[] buf,164int start, int count) {165if (count > 4) {166throw new IllegalArgumentException(167"Cannot handle more than 4 bytes");168}169170for (int i = count-1; i >= 0; i--) {171buf[start+i] = (byte)(num & 0xff);172num >>>= 8;173}174}175}176177class UDPClient extends NetClient {178InetAddress iaddr;179int iport;180int bufSize = 65507;181DatagramSocket dgSocket;182DatagramPacket dgPacketIn;183184UDPClient(String hostname, int port, int timeout)185throws UnknownHostException, SocketException {186iaddr = InetAddress.getByName(hostname);187iport = port;188dgSocket = new DatagramSocket();189dgSocket.setSoTimeout(timeout);190dgSocket.connect(iaddr, iport);191}192193@Override194public void send(byte[] data) throws IOException {195DatagramPacket dgPacketOut = new DatagramPacket(data, data.length,196iaddr, iport);197dgSocket.send(dgPacketOut);198}199200@Override201public byte[] receive() throws IOException {202byte ibuf[] = new byte[bufSize];203dgPacketIn = new DatagramPacket(ibuf, ibuf.length);204try {205dgSocket.receive(dgPacketIn);206}207catch (SocketException e) {208if (e instanceof PortUnreachableException) {209throw e;210}211dgSocket.receive(dgPacketIn);212}213byte[] data = new byte[dgPacketIn.getLength()];214System.arraycopy(dgPacketIn.getData(), 0, data, 0,215dgPacketIn.getLength());216return data;217}218219@Override220public void close() {221dgSocket.close();222}223}224225226