Commit 9dbe588f authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan
Browse files

rpc: utility class for InetSocketAddress manipulation

Going into direction of IPv6. Uses Google Core Libraries for Java 1.5+
parent 579fade7
......@@ -233,6 +233,11 @@
<artifactId>logback-classic</artifactId>
<version>0.9.21</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>r05</version>
</dependency>
<!--
LOCAL JARS
......
......@@ -5,6 +5,7 @@ package org.dcache.chimera.nfs.v4;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.dcache.utils.net.InetSocketAddresses;
class ClientCB {
......@@ -68,8 +69,8 @@ class ClientCB {
try {
System.out.println(new ClientCB("127.0.0.2.4.63", "tcp", 1005));
System.out.println(new ClientCB( HimeraNFS4Utils.inetAddress2rAddr("127.0.0.2", 1087) , "tcp", 1005));
}catch(Exception e) {
System.out.println(new ClientCB(InetSocketAddresses.uaddrOf("127.0.0.2", 1087), "tcp", 1005));
} catch (Exception e) {
e.printStackTrace();
}
......
......@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import org.dcache.utils.net.InetSocketAddresses;
/**
*
......@@ -138,7 +139,7 @@ public class DeviceManager implements NFSv41DeviceManager {
file_type.nflda_multipath_ds_list[i].value[0] = new netaddr4();
file_type.nflda_multipath_ds_list[i].value[0].na_r_addr =
HimeraNFS4Utils.inetAddress2rAddr(deviceAddress[i]);
InetSocketAddresses.uaddrOf(deviceAddress[i]);
file_type.nflda_multipath_ds_list[i].value[0].na_r_netid = "tcp";
}
......
......@@ -9,8 +9,6 @@ import org.dcache.chimera.nfs.v4.xdr.utf8str_cs;
import org.dcache.chimera.nfs.v4.xdr.nfs4_prot;
import org.dcache.chimera.nfs.v4.xdr.utf8str_cis;
import org.dcache.chimera.nfs.v4.xdr.utf8string;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import org.dcache.xdr.RpcAuthType;
import org.dcache.xdr.RpcAuthTypeUnix;
......@@ -56,36 +54,6 @@ public class HimeraNFS4Utils {
}
public static String inetAddress2rAddr( InetSocketAddress address) {
byte[] host_part = address.getAddress().getAddress();
int port = address.getPort();
int port_part[] = new int[2];
port_part[0] = (port & 0xff00) >> 8;
port_part[1] = port & 0x00ff;
StringBuilder sb = new StringBuilder();
sb.append(0xFF & host_part[0]).append(".");
sb.append(0xFF & host_part[1]).append(".");
sb.append(0xFF & host_part[2]).append(".");
sb.append(0xFF & host_part[3]).append(".");
sb.append(0xFF & port_part[0]).append(".");
sb.append(0xFF & port_part[1]);
return sb.toString();
}
public static String inetAddress2rAddr( String host, int port) throws UnknownHostException {
return inetAddress2rAddr( new InetSocketAddress(host, port));
}
public static String aceToString(nfsace4 ace) {
String who = new String(ace.who.value.value);
......
......@@ -9,6 +9,7 @@ import org.dcache.chimera.nfs.v4.xdr.nfs_opnum4;
import org.dcache.chimera.nfs.v4.xdr.SETCLIENTID4resok;
import org.dcache.chimera.nfs.v4.xdr.SETCLIENTID4res;
import org.dcache.chimera.nfs.ChimeraNFSException;
import org.dcache.utils.net.InetSocketAddresses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -46,7 +47,7 @@ public class OperationSETCLIENTID extends AbstractNFSv4Operation {
try {
ClientCB cb = new ClientCB(r_addr, r_netid, program);
// TODO: work around. client should send correct IP
cb = new ClientCB( HimeraNFS4Utils.inetAddress2rAddr(context.getRpcCall().getTransport().getRemoteSocketAddress() ), r_netid, program);
cb = new ClientCB( InetSocketAddresses.uaddrOf(context.getRpcCall().getTransport().getRemoteSocketAddress() ), r_netid, program);
_log.debug("Client callback: {}", cb);
client.setCB(cb);
}catch(Exception ignode_call_back) {
......
......@@ -6,7 +6,6 @@ import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
......@@ -52,6 +51,7 @@ import org.dcache.chimera.nfs.v4.xdr.utf8str_cs;
import org.dcache.chimera.nfs.v4.xdr.utf8string;
import org.dcache.chimera.nfs.v4.xdr.verifier4;
import org.dcache.chimera.posix.Stat;
import org.dcache.utils.net.InetSocketAddresses;
import org.dcache.xdr.IpProtocolType;
import org.dcache.xdr.OncRpcException;
......@@ -1096,7 +1096,8 @@ public class Main {
nfsv4_1_file_layout_ds_addr4 addr = GetDeviceListStub.decodeFileDevice(compound4res.resarray[1].opgetdeviceinfo.gdir_resok4.gdir_device_addr.da_addr_body);
InetSocketAddress inetAddr = device2Address(addr.nflda_multipath_ds_list[0].value[0].na_r_addr);
InetSocketAddress inetAddr = InetSocketAddresses.forUaddrString(
addr.nflda_multipath_ds_list[0].value[0].na_r_addr);
_knowDevices.put(deviceId, inetAddr);
......@@ -1106,31 +1107,6 @@ public class Main {
}
}
public static final InetSocketAddress device2Address(String deviceId)
throws UnknownHostException {
String[] cb_addr = deviceId.trim().split("[.]");
byte[] addr = new byte[4];
addr[0] = Integer.valueOf(cb_addr[0]).byteValue();
addr[1] = Integer.valueOf(cb_addr[1]).byteValue();
addr[2] = Integer.valueOf(cb_addr[2]).byteValue();
addr[3] = Integer.valueOf(cb_addr[3]).byteValue();
InetAddress inetAddr = InetAddress.getByAddress(addr);
Integer p1 = new Integer(cb_addr[4]);
Integer p2 = new Integer(cb_addr[5]);
int port = p1.intValue();
port <<= 8;
port |= p2.intValue();
return new InetSocketAddress(inetAddr, port);
}
private void get_devicelist() throws OncRpcException, IOException {
List<nfs_argop4> ops = new LinkedList<nfs_argop4>();
......
/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.utils.net;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import com.google.common.net.InetAddresses;
/**
* Utility class for InetSocketAddress manipulations.
* @author tigran
*/
public class InetSocketAddresses {
/* utility class. No instances are allowed */
private InetSocketAddresses() {}
/**
* Convert UADDR string into {@link InetSocketAddress} as defined in rfc5665.
* <pre>
* IPv4 format:
* h1.h2.h3.h4.p1.p2
*
* The prefix "h1.h2.h3.h4" is the standard textual form for
* representing an IPv4 address, which is always four octets long.
* Assuming big-endian ordering, h1, h2, h3, and h4 are, respectively,
* the first through fourth octets each converted to ASCII-decimal. The
* suffix "p1.p2" is a textual form for representing a service port.
* Assuming big-endian ordering, p1 and p2 are, respectively, the first
* and second octets each converted to ASCII-decimal. For example, if a
* host, in big-endian order, has an address in hexadecimal of
* 0xC0000207 and there is a service listening on, in big-endian order,
* port 0xCB51 (decimal 52049), then the complete uaddr is
* "192.0.2.7.203.81".
*
* IPv6:
* x1:x2:x3:x4:x5:x6:x7:x8.p1.p2
* The suffix "p1.p2" is the service port, and is computed the same way
* as with uaddrs for transports over IPv4 (see Section 5.2.3.3). The
* prefix "x1:x2:x3:x4:x5:x6:x7:x8" is the preferred textual form for
* representing an IPv6 address as defined in Section 2.2 of RFC 4291
* Additionally, the two alternative forms specified in Section 2.2
* of RFC 4291 are also acceptable.
* </pre>
* @param address
* @return socket address
* @throws UnknownHostException
*/
public static InetSocketAddress forUaddrString(String uaddr) throws UnknownHostException {
int secondPort = uaddr.lastIndexOf('.');
if( secondPort == -1 ) {
throw new IllegalArgumentException("address " + uaddr + " doesn't match rfc5665");
}
int firstPort = uaddr.lastIndexOf('.', secondPort -1);
if( secondPort == -1 ) {
throw new IllegalArgumentException("address " + uaddr + " doesn't match rfc5665");
}
InetAddress inetAddr = InetAddresses.forString(uaddr.substring(0, firstPort));
int p1 = Integer.parseInt(uaddr.substring(firstPort +1, secondPort));
int p2 = Integer.parseInt(uaddr.substring(secondPort +1));
int port = (p1 << 8) + p2;
return new InetSocketAddress(inetAddr, port);
}
/**
* Convert {@link InetSocketAddress} to it's UADDR representation as defined in rfc5665.
* @param socketAddress
* @return uaddr.
*/
public static String uaddrOf(InetSocketAddress socketAddress) {
int port = socketAddress.getPort();
int port_part[] = new int[2];
port_part[0] = (port & 0xff00) >> 8;
port_part[1] = port & 0x00ff;
return socketAddress.getAddress().getHostAddress() +
"." + port_part[0] + "." + port_part[1];
}
/**
* Convert <code>hostname</code> and <code>port</code> into UADDR representation
* as defined in rfc5665.
* @param host
* @param port
* @return uaddr
*/
public static String uaddrOf(String host, int port) {
return uaddrOf( new InetSocketAddress(host, port));
}
}
package org.dcache.utils.net;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import org.junit.Test;
import static org.junit.Assert.*;
public class InetSocketAddressesTest {
@Test
public void testLocalHostV4() throws Exception {
String uaddr = "127.0.0.1.203.81";
InetSocketAddress socketAddress = InetSocketAddresses.forUaddrString(uaddr);
assertEquals("port mismatch", 52049, socketAddress.getPort());
assertEquals("host mismatch", InetAddress.getByName("127.0.0.1"),
socketAddress.getAddress());
}
@Test
public void testLocalHostV6() throws Exception {
String uaddr = "::1.203.81";
InetSocketAddress socketAddress = InetSocketAddresses.forUaddrString(uaddr);
assertEquals("port mismatch", 52049, socketAddress.getPort());
assertEquals("host mismatch", InetAddress.getByName("::1"),
socketAddress.getAddress());
}
@Test
public void testLocalHostV4Revert() throws Exception {
String uaddr = "127.0.0.1.203.81";
InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),52049);
assertEquals("reverce convertion failed", uaddr,
InetSocketAddresses.uaddrOf(socketAddress));
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment