/* * Copyright (C) 2006 Open Cloud Ltd. * * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Middleware LLC. * * This library is free software; you can redistribute it and/or * modify it under the terms of version 2.1 of the GNU Lesser * General Public License as published by the Free Software Foundation. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package net.java.slee.resource.diameter.base.events.avp; import java.net.URI; import java.net.URISyntaxException; import java.util.StringTokenizer; /** * Java class to represent the DiameterURI AVP type. * * The DiameterURI MUST follow the Uniform Resource Identifiers (URI) syntax [URI] rules specified below. <pre> "aaa://" FQDN [ port ] [ transport ] [ protocol ] ; No transport security "aaas://" FQDN [ port ] [ transport ] [ protocol ] ; Transport security used FQDN = Fully Qualified Host Name port = ":" 1*DIGIT ; One of the ports used to listen for incoming connections. ; If absent, the default Diameter port (3868) is assumed. transport = ";transport=" transport-protocol ; One of the transports used to listen ; for incoming connections. If absent, ; the default SCTP [SCTP] protocol is ; assumed. UDP MUST NOT be used when ; the aaa-protocol field is set to ; diameter. transport-protocol = ( "tcp" / "sctp" / "udp" ) protocol = ";protocol=" aaa-protocol ; If absent, the default AAA protocol ; is diameter. aaa-protocol = ( "diameter" / "radius" / "tacacs+" ) The following are examples of valid Diameter host identities: aaa://host.example.com;transport=tcp aaa://host.example.com:6666;transport=tcp aaa://host.example.com;protocol=diameter aaa://host.example.com:6666;protocol=diameter aaa://host.example.com:6666;transport=tcp;protocol=diameter aaa://host.example.com:1813;transport=udp;protocol=radius </pre> * * @author Open Cloud */ public class DiameterURI { public DiameterURI(String fqdn, int port, int protocol, int transport, boolean secure) { this.secure = secure; this.hostname = fqdn; this.port = port; this.protocol = protocol; this.transport = transport; } public DiameterURI(String uri) throws URISyntaxException { parseUri(uri); } public boolean getSecure() { return secure; } public String getHostname() { return hostname; } public int getPort() { return port; } public int getProtocol() { return protocol; } public int getTransport() { return transport; } /** * Return the contents of this URI as a byte array. Technically this type * derives from OctetString, so we need to be able to return the value in * the base type. * * @return the result of toString().getBytes() */ public byte[] getBytes() { return toString().getBytes(); } public String toString() { StringBuffer buffer = new StringBuffer(secure ? "aaas" : "aaa"); buffer.append("://").append(hostname); if (port != DEFAULT_DIAMETER_PORT) { buffer.append(":").append(port); } if (transport != TRANSPORT_TCP) { buffer.append(";transport="); switch (transport) { case TRANSPORT_SCTP: buffer.append("sctp"); break; case TRANSPORT_UDP: buffer.append("udp"); break; } } if (protocol != PROTOCOL_DIAMETER) { buffer.append(";protocol="); switch (protocol) { case PROTOCOL_RADIUS: buffer.append("radius"); break; case PROTOCOL_TACACSPLUS: buffer.append("tacacs+"); break; } } return buffer.toString(); } private void parseUri(String uri) throws URISyntaxException { URI parsedUri; int semiColonPos = uri.indexOf(';'); if (semiColonPos > 0) { parsedUri = new URI(uri.substring(0, semiColonPos)); StringTokenizer st = new StringTokenizer(uri.substring(semiColonPos + 1), ";=", false); while (st.hasMoreTokens()) { String name = st.nextToken(); if (name.equals("transport")) { transport = matchTransport(st.nextToken()); } else if (name.equals("protocol")) { protocol = matchProtocol(st.nextToken()); } else { throw new URISyntaxException(name, "unknown URI option"); } } } else { parsedUri = new URI(uri); } if (parsedUri.getScheme().equals("aaa")) { secure = false; } else if (parsedUri.getScheme().equals("aaas")) { secure = true; } else { throw new URISyntaxException(parsedUri.getScheme(), "invalid scheme (must be aaa or aaas)"); } hostname = parsedUri.getHost(); port = parsedUri.getPort() > 0 ? parsedUri.getPort() : DEFAULT_DIAMETER_PORT; } private int matchTransport(String transportString) { if (transportString.equals("tcp")) { return TRANSPORT_TCP; } else if (transportString.equals("sctp")) { return TRANSPORT_SCTP; } else if (transportString.equals("udp")) { return TRANSPORT_UDP; } else { throw new IllegalArgumentException("Unknown transport: " + transportString); } } private int matchProtocol(String protocolString) { if (protocolString.equals("diameter")) { return PROTOCOL_DIAMETER; } else if (protocolString.equals("radius")) { return PROTOCOL_RADIUS; } else if (protocolString.equals("tacacs+")) { return PROTOCOL_TACACSPLUS; } else { throw new IllegalArgumentException("Unknown protocol: " + protocolString); } } public static final int TRANSPORT_TCP = 0; public static final int TRANSPORT_SCTP = 1; public static final int TRANSPORT_UDP = 2; public static final int PROTOCOL_DIAMETER = 0; public static final int PROTOCOL_RADIUS = 1; public static final int PROTOCOL_TACACSPLUS = 2; private static final int DEFAULT_DIAMETER_PORT = 3868; private boolean secure; // false = aaa: true = aaas: private String hostname; private int port; private int protocol; private int transport; public boolean equals(Object that) { if (this == that) return true; if(that == null) return false; return this.toString().equals(that.toString()); } }