001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net;
019
020import java.io.IOException;
021import java.net.InetAddress;
022import java.net.InetSocketAddress;
023import java.net.Proxy;
024import java.net.ServerSocket;
025import java.net.Socket;
026import java.net.UnknownHostException;
027
028import javax.net.SocketFactory;
029
030/**
031 * DefaultSocketFactory implements the SocketFactory interface by simply wrapping the java.net.Socket and java.net.ServerSocket constructors. It is the default
032 * SocketFactory used by {@link org.apache.commons.net.SocketClient} implementations.
033 *
034 *
035 * @see SocketFactory
036 * @see SocketClient
037 * @see SocketClient#setSocketFactory
038 */
039public class DefaultSocketFactory extends SocketFactory {
040    /** The proxy to use when creating new sockets. */
041    private final Proxy connProxy;
042
043    /**
044     * Constructs a new instance.
045     */
046    public DefaultSocketFactory() {
047        this(null);
048    }
049
050    /**
051     * A constructor for sockets with proxy support.
052     *
053     * @param proxy The Proxy to use when creating new Sockets.
054     * @since 3.2
055     */
056    public DefaultSocketFactory(final Proxy proxy) {
057        connProxy = proxy;
058    }
059
060    /**
061     * Creates a ServerSocket bound to a specified port. A port of 0 will create the ServerSocket on a system-determined free port.
062     *
063     * @param port The port on which to listen, or 0 to use any free port.
064     * @return A ServerSocket that will listen on a specified port.
065     * @throws IOException If an I/O error occurs while creating the ServerSocket.
066     */
067    public ServerSocket createServerSocket(final int port) throws IOException {
068        return new ServerSocket(port);
069    }
070
071    /**
072     * Creates a ServerSocket bound to a specified port with a given maximum queue length for incoming connections. A port of 0 will create the ServerSocket on
073     * a system-determined free port.
074     *
075     * @param port    The port on which to listen, or 0 to use any free port.
076     * @param backlog The maximum length of the queue for incoming connections.
077     * @return A ServerSocket that will listen on a specified port.
078     * @throws IOException If an I/O error occurs while creating the ServerSocket.
079     */
080    public ServerSocket createServerSocket(final int port, final int backlog) throws IOException {
081        return new ServerSocket(port, backlog);
082    }
083
084    /**
085     * Creates a ServerSocket bound to a specified port on a given local address with a given maximum queue length for incoming connections. A port of 0 will
086     * create the ServerSocket on a system-determined free port.
087     *
088     * @param port     The port on which to listen, or 0 to use any free port.
089     * @param backlog  The maximum length of the queue for incoming connections.
090     * @param bindAddr The local address to which the ServerSocket should bind.
091     * @return A ServerSocket that will listen on a specified port.
092     * @throws IOException If an I/O error occurs while creating the ServerSocket.
093     */
094    public ServerSocket createServerSocket(final int port, final int backlog, final InetAddress bindAddr) throws IOException {
095        return new ServerSocket(port, backlog, bindAddr);
096    }
097
098    /**
099     * Creates an unconnected Socket.
100     *
101     * @return A new unconnected Socket.
102     * @throws IOException If an I/O error occurs while creating the Socket.
103     * @since 3.2
104     */
105    @Override
106    public Socket createSocket() throws IOException {
107        if (connProxy != null) {
108            return new Socket(connProxy);
109        }
110        return new Socket();
111    }
112
113    /**
114     * Creates a Socket connected to the given host and port.
115     *
116     * @param address The address of the host to connect to.
117     * @param port    The port to connect to.
118     * @return A Socket connected to the given host and port.
119     * @throws IOException If an I/O error occurs while creating the Socket.
120     */
121    @Override
122    public Socket createSocket(final InetAddress address, final int port) throws IOException {
123        if (connProxy != null) {
124            final Socket s = new Socket(connProxy);
125            s.connect(new InetSocketAddress(address, port));
126            return s;
127        }
128        return new Socket(address, port);
129    }
130
131    /**
132     * Creates a Socket connected to the given host and port and originating from the specified local address and port.
133     *
134     * @param address   The address of the host to connect to.
135     * @param port      The port to connect to.
136     * @param localAddr The local address to use.
137     * @param localPort The local port to use.
138     * @return A Socket connected to the given host and port.
139     * @throws IOException If an I/O error occurs while creating the Socket.
140     */
141    @Override
142    public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddr, final int localPort) throws IOException {
143        if (connProxy != null) {
144            final Socket s = new Socket(connProxy);
145            s.bind(new InetSocketAddress(localAddr, localPort));
146            s.connect(new InetSocketAddress(address, port));
147            return s;
148        }
149        return new Socket(address, port, localAddr, localPort);
150    }
151
152    /**
153     * Creates a Socket connected to the given host and port.
154     *
155     * @param host The hostname to connect to.
156     * @param port The port to connect to.
157     * @return A Socket connected to the given host and port.
158     * @throws UnknownHostException If the hostname cannot be resolved.
159     * @throws IOException          If an I/O error occurs while creating the Socket.
160     */
161    @Override
162    public Socket createSocket(final String host, final int port) throws UnknownHostException, IOException {
163        if (connProxy != null) {
164            final Socket s = new Socket(connProxy);
165            s.connect(new InetSocketAddress(host, port));
166            return s;
167        }
168        return new Socket(host, port);
169    }
170
171    /**
172     * Creates a Socket connected to the given host and port and originating from the specified local address and port.
173     *
174     * @param host      The hostname to connect to.
175     * @param port      The port to connect to.
176     * @param localAddr The local address to use.
177     * @param localPort The local port to use.
178     * @return A Socket connected to the given host and port.
179     * @throws UnknownHostException If the hostname cannot be resolved.
180     * @throws IOException          If an I/O error occurs while creating the Socket.
181     */
182    @Override
183    public Socket createSocket(final String host, final int port, final InetAddress localAddr, final int localPort) throws UnknownHostException, IOException {
184        if (connProxy != null) {
185            final Socket s = new Socket(connProxy);
186            s.bind(new InetSocketAddress(localAddr, localPort));
187            s.connect(new InetSocketAddress(host, port));
188            return s;
189        }
190        return new Socket(host, port, localAddr, localPort);
191    }
192}