mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2024-11-25 12:35:36 +01:00
IPv6 is my true love
This commit is contained in:
parent
0b101d1278
commit
779e1dab4d
@ -15,17 +15,18 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import us.myles.ViaVersion.packets.State
|
import us.myles.ViaVersion.packets.State
|
||||||
|
import java.net.Inet4Address
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.net.InetSocketAddress
|
import java.net.InetSocketAddress
|
||||||
|
|
||||||
fun createBackChannel(handler: MinecraftHandler, socketAddr: InetSocketAddress, state: State): ChannelFuture {
|
private fun createBackChannel(handler: MinecraftHandler, socketAddr: InetSocketAddress, state: State): ChannelFuture {
|
||||||
return Bootstrap()
|
return Bootstrap()
|
||||||
.handler(BackEndInit(handler.data))
|
.handler(BackEndInit(handler.data))
|
||||||
.channelFactory(channelSocketFactory())
|
.channelFactory(channelSocketFactory())
|
||||||
.group(handler.data.frontChannel.eventLoop())
|
.group(handler.data.frontChannel.eventLoop())
|
||||||
.option(ChannelOption.IP_TOS, 0x18)
|
.option(ChannelOption.IP_TOS, 0x18)
|
||||||
.option(ChannelOption.TCP_NODELAY, true)
|
.option(ChannelOption.TCP_NODELAY, true)
|
||||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15_000) // Half of mc timeout
|
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) // We need to show the error before the client timeout
|
||||||
.connect(socketAddr)
|
.connect(socketAddr)
|
||||||
.addListener(ChannelFutureListener {
|
.addListener(ChannelFutureListener {
|
||||||
if (it.isSuccess) {
|
if (it.isSuccess) {
|
||||||
@ -41,29 +42,63 @@ fun createBackChannel(handler: MinecraftHandler, socketAddr: InetSocketAddress,
|
|||||||
forward(handler, packet, true)
|
forward(handler, packet, true)
|
||||||
|
|
||||||
handler.data.frontChannel.setAutoRead(true)
|
handler.data.frontChannel.setAutoRead(true)
|
||||||
} else {
|
|
||||||
// We're in the event loop
|
|
||||||
handler.disconnect("Couldn't connect: " + it.cause().toString())
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun tryBackAddress(
|
||||||
|
handler: MinecraftHandler,
|
||||||
|
iterator: Iterator<InetAddress>,
|
||||||
|
port: Int,
|
||||||
|
state: State,
|
||||||
|
success: () -> Unit,
|
||||||
|
) {
|
||||||
|
val fail = { e: Throwable ->
|
||||||
|
if (!iterator.hasNext()) {
|
||||||
|
// We're in the event loop
|
||||||
|
handler.disconnect("Couldn't connect: $e")
|
||||||
|
} else if (handler.data.frontChannel.isActive) {
|
||||||
|
tryBackAddress(handler, iterator, port, state, success)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val socketAddr = InetSocketAddress(iterator.next(), port)
|
||||||
|
|
||||||
|
if (checkLocalAddress(socketAddr.address)
|
||||||
|
|| matchesAddress(socketAddr, VIAaaSConfig.blockedBackAddresses)
|
||||||
|
|| !matchesAddress(socketAddr, VIAaaSConfig.allowedBackAddresses)
|
||||||
|
) {
|
||||||
|
throw SecurityException("Not allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
createBackChannel(handler, socketAddr, state).addListener {
|
||||||
|
if (it.isSuccess) {
|
||||||
|
success()
|
||||||
|
} else {
|
||||||
|
fail(it.cause())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
handler.data.frontChannel.eventLoop().submit {
|
||||||
|
fail(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun connectBack(handler: MinecraftHandler, address: String, port: Int, state: State, success: () -> Unit) {
|
fun connectBack(handler: MinecraftHandler, address: String, port: Int, state: State, success: () -> Unit) {
|
||||||
handler.data.frontChannel.setAutoRead(false)
|
handler.data.frontChannel.setAutoRead(false)
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val srvResolved = resolveSrv(address, port)
|
val srvResolved = resolveSrv(address, port)
|
||||||
|
|
||||||
val socketAddr = InetSocketAddress(InetAddress.getByName(srvResolved.first), srvResolved.second)
|
val iterator = InetAddress.getAllByName(srvResolved.first)
|
||||||
|
.groupBy { it is Inet4Address }
|
||||||
|
.toSortedMap() // I'm sorry, IPv4, but my true love is IPv6... We can still be friends though...
|
||||||
|
.map { it.value.random() }
|
||||||
|
.iterator()
|
||||||
|
|
||||||
if (checkLocalAddress(socketAddr.address)
|
if (!iterator.hasNext()) throw IllegalArgumentException("Hostname has no IP address")
|
||||||
|| matchesAddress(socketAddr, VIAaaSConfig.blockedBackAddresses)
|
tryBackAddress(handler, iterator, srvResolved.second, state, success)
|
||||||
|| !matchesAddress(socketAddr, VIAaaSConfig.allowedBackAddresses)
|
|
||||||
) {
|
|
||||||
throw SecurityException("Not allowed")
|
|
||||||
}
|
|
||||||
|
|
||||||
createBackChannel(handler, socketAddr, state).addListener { if (it.isSuccess) success() }
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
handler.data.frontChannel.eventLoop().submit {
|
handler.data.frontChannel.eventLoop().submit {
|
||||||
handler.disconnect("Couldn't connect: $e")
|
handler.disconnect("Couldn't connect: $e")
|
||||||
|
Loading…
Reference in New Issue
Block a user