Discord bot that plays music from every website ever via youtube-dl
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Chords/src/main/java/moe/nekojimi/chords/LocalBindSocketFactory.java

112 lines
3.7 KiB

/*
* Copyright (C) 2022 jimj316
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package moe.nekojimi.chords;
import java.io.IOException;
import java.net.*;
import javax.net.SocketFactory;
/**
*
* @author jimj316
*/
public class LocalBindSocketFactory extends SocketFactory
{
private InetAddress localAddress;
public InetAddress getLocalAddress()
{
return localAddress;
}
public void setLocalAddress(InetAddress localAddress)
{
this.localAddress = localAddress;
}
@Override
public Socket createSocket() throws IOException
{
return new LocalBoundSocket();
// throw new RuntimeException("Trying to create an empty socket!");
}
private InetSocketAddress findFreeSocketAddress()
{
return new InetSocketAddress(localAddress, findFreePort(localAddress));
}
@Override
public Socket createSocket(String remoteAddr, int remotePort) throws IOException, UnknownHostException
{
return createSocket(remoteAddr, remotePort, localAddress, findFreePort(localAddress));
}
@Override
public Socket createSocket(String remoteAddr, int remotePort, InetAddress x, int localPort) throws IOException, UnknownHostException
{
return createSocket(InetAddress.getByName(remoteAddr), remotePort, localAddress, localPort);
}
@Override
public Socket createSocket(InetAddress remoteAddr, int remotePort) throws IOException
{
return createSocket(remoteAddr, remotePort, localAddress, findFreePort(localAddress));
}
@Override
public Socket createSocket(InetAddress remoteAddr, int remotePort, InetAddress x, int localPort) throws IOException
{
System.out.println("Requested socket; " + localAddress + ":" + localPort + " -> " + remoteAddr + ":" + remotePort);
Socket socket = new Socket(remoteAddr, remotePort, localAddress, localPort);
System.out.println("Returned socket; " + socket.getLocalSocketAddress() + ":" + socket.getLocalPort() + " -> " + socket.getRemoteSocketAddress() + ":" + socket.getPort());
return socket;
}
private static int findFreePort(InetAddress localAddr)
{
int port = 0;
// For ServerSocket port number 0 means that the port number is automatically allocated.
try (ServerSocket socket = new ServerSocket(0, 0, localAddr))
{
// Disable timeout and reuse address after closing the socket.
socket.setReuseAddress(true);
port = socket.getLocalPort();
} catch (IOException ignored)
{
}
if (port > 0)
{
return port;
}
throw new RuntimeException("Could not find a free port");
}
private class LocalBoundSocket extends Socket
{
@Override
public void bind(SocketAddress bindpoint) throws IOException
{
InetSocketAddress localAddress = findFreeSocketAddress();
System.err.println("LocalBoundSocket NOT binding to " + bindpoint + ", using " + localAddress + " instead!");
super.bind(localAddress);
}
}
}