001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.util;
007:
008: import java.io.IOException;
009: import java.net.BindException;
010: import java.net.InetAddress;
011: import java.net.ServerSocket;
012: import java.net.Socket;
013: import java.net.UnknownHostException;
014: import java.sql.SQLException;
015:
016: import org.h2.constant.ErrorCode;
017: import org.h2.constant.SysProperties;
018: import org.h2.message.Message;
019: import org.h2.security.SecureSocketFactory;
020:
021: /**
022: * This utility class contains socket helper functions.
023: */
024: public class NetUtils {
025:
026: private static InetAddress bindAddress;
027:
028: public static Socket createLoopbackSocket(int port, boolean ssl)
029: throws IOException {
030: InetAddress address = getBindAddress();
031: if (address == null) {
032: address = InetAddress.getLocalHost();
033: }
034: return createSocket(address.getHostAddress(), port, ssl);
035: }
036:
037: public static Socket createSocket(String server, int defaultPort,
038: boolean ssl) throws IOException {
039: int port = defaultPort;
040: // IPv6: RFC 2732 format is '[a:b:c:d:e:f:g:h]' or
041: // '[a:b:c:d:e:f:g:h]:port'
042: // RFC 2396 format is 'a.b.c.d' or 'a.b.c.d:port' or 'hostname' or
043: // 'hostname:port'
044: int startIndex = server.startsWith("[") ? server.indexOf(']')
045: : 0;
046: int idx = server.indexOf(':', startIndex);
047: if (idx >= 0) {
048: port = MathUtils.decodeInt(server.substring(idx + 1));
049: server = server.substring(0, idx);
050: }
051: InetAddress address = InetAddress.getByName(server);
052: return createSocket(address, port, ssl);
053: }
054:
055: public static Socket createSocket(InetAddress address, int port,
056: boolean ssl) throws IOException {
057: if (ssl) {
058: SecureSocketFactory f = SecureSocketFactory.getInstance();
059: return f.createSocket(address, port);
060: } else {
061: return new Socket(address, port);
062: }
063: }
064:
065: public static ServerSocket createServerSocket(int port, boolean ssl)
066: throws SQLException {
067: try {
068: return createServerSocketTry(port, ssl);
069: } catch (SQLException e) {
070: // try again
071: return createServerSocketTry(port, ssl);
072: }
073: }
074:
075: /**
076: * Get the bind address if the system property h2.bindAddress is set, or
077: * null if not.
078: *
079: * @return the bind address
080: */
081: public static InetAddress getBindAddress()
082: throws UnknownHostException {
083: String host = SysProperties.BIND_ADDRESS;
084: if (host == null || host.length() == 0) {
085: return null;
086: }
087: synchronized (NetUtils.class) {
088: if (bindAddress == null) {
089: bindAddress = InetAddress.getByName(host);
090: }
091: }
092: return bindAddress;
093: }
094:
095: private static ServerSocket createServerSocketTry(int port,
096: boolean ssl) throws SQLException {
097: try {
098: if (ssl) {
099: SecureSocketFactory f = SecureSocketFactory
100: .getInstance();
101: return f.createServerSocket(port);
102: } else {
103: InetAddress bindAddress = getBindAddress();
104: if (bindAddress == null) {
105: return new ServerSocket(port);
106: } else {
107: return new ServerSocket(port, 0, bindAddress);
108: }
109: }
110: } catch (BindException be) {
111: throw Message.getSQLException(
112: ErrorCode.EXCEPTION_OPENING_PORT_2, new String[] {
113: "" + port, be.toString() }, be);
114: } catch (IOException e) {
115: throw Message.convertIOException(e, "port: " + port
116: + " ssl: " + ssl);
117: }
118: }
119:
120: public static boolean isLoopbackAddress(Socket socket) {
121: boolean result = true;
122: //#ifdef JDK14
123: result = socket.getInetAddress().isLoopbackAddress();
124: //#endif
125: return result;
126: }
127:
128: public static ServerSocket closeSilently(ServerSocket socket) {
129: if (socket != null) {
130: try {
131: socket.close();
132: } catch (IOException e) {
133: // ignore
134: }
135: }
136: return null;
137: }
138:
139: public static String getLocalAddress() {
140: InetAddress bind = null;
141: try {
142: bind = getBindAddress();
143: } catch (UnknownHostException e) {
144: // ignore
145: }
146: return bind == null ? "localhost" : bind.getHostAddress();
147: }
148:
149: }
|