From 03d3ad852b255d134de35c0ed358aa08fb5647ed Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Fri, 18 Nov 2022 01:28:31 +0800 Subject: [PATCH 01/15] Turning toIpV4Long function into MMP, fix #2349 --- .../network/protocol/packet/login/StatSvc.kt | 7 +---- .../network/protocol/packet/login/StatSvc.kt | 27 +++++++++++++++++++ .../src/mingwX64Main/cinterop/Socket.def | 17 ++++++++++++ .../network/protocol/packet/login/StatSvc.kt | 17 ++++++++++++ mirai-core/src/unixMain/cinterop/Socket.def | 22 +++++++++++++++ .../network/protocol/packet/login/StatSvc.kt | 17 ++++++++++++ 6 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt create mode 100644 mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt create mode 100644 mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt index 4ce1364ed8c..472cf5d789f 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -425,9 +425,4 @@ internal class StatSvc { } } -internal fun String.toIpV4Long(): Long { - if (isEmpty()) return 0 - val split = split('.') - if (split.size != 4) return 0 - return split.mapToByteArray { it.toUByte().toByte() }.toInt().toLongUnsigned() -} +internal expect fun String.toIpV4Long(): Long diff --git a/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt new file mode 100644 index 00000000000..ff50712fb42 --- /dev/null +++ b/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2019-2022 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +package net.mamoe.mirai.internal.network.protocol.packet.login + +import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.toLongUnsigned +import java.net.Inet4Address +import java.net.UnknownHostException + +internal actual fun String.toIpV4Long(): Long { + return if (isEmpty()) { + 0 + } else { + try { + Inet4Address.getByName(this).address.toInt().toLongUnsigned() + } catch (e: UnknownHostException) { + -2 + } + } +} \ No newline at end of file diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index debd8e44cff..45389713c9d 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -7,6 +7,23 @@ headers = winsock.h #include #include #include +#include + +static unsigned long get_ulong_ip_by_name(char* host) { + DNS_RECORDA* dns_record; + if (strlen(host) == 0) { + return 0; + } + int dns_result = DnsQuery_A(host, DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &dns_record, NULL); + if (dns_result == DNS_RCODE_NOERROR && dns_record != NULL) { + unsigned long result = dns_record->Data.A.IpAddress; + DnsRecordListFree(dns_record, DnsFreeRecordList); + return result; + } + else { + return -2; + } +} static SOCKET socket_create_connect(char *host, unsigned short port) { SOCKADDR_STORAGE local_addr = {0}; diff --git a/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt new file mode 100644 index 00000000000..c96c0ad7f6e --- /dev/null +++ b/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2019-2022 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +package net.mamoe.mirai.internal.network.protocol.packet.login + +import kotlinx.cinterop.cstr +import sockets.get_ulong_ip_by_name + +internal actual fun String.toIpV4Long(): Long { + return get_ulong_ip_by_name(this.cstr).toLong(); +} \ No newline at end of file diff --git a/mirai-core/src/unixMain/cinterop/Socket.def b/mirai-core/src/unixMain/cinterop/Socket.def index 777694743aa..b861820299f 100644 --- a/mirai-core/src/unixMain/cinterop/Socket.def +++ b/mirai-core/src/unixMain/cinterop/Socket.def @@ -5,6 +5,28 @@ headers = netdb.h #include #include #include +#include +#include +#include + +static unsigned long get_ulong_ip_by_name(char* host) { + unsigned long result; + if (strlen(host) == 0) { + return 0; + } + struct hostent* dns_result = gethostbyname(host); + if (dns_result != NULL) { + char** list_ptr = dns_result->h_addr_list; + char ip_str[16]; + if (inet_ntop(dns_result->h_addrtype, *list_ptr, ip_str, sizeof(ip_str)) != NULL) { + result = inet_addr(ip_str); + if (result > 0) { + return result; + } + } + } + return -2; +} static int socket_create_connect(char *host, ushort port) { struct hostent *he; diff --git a/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt new file mode 100644 index 00000000000..bd1fea17eca --- /dev/null +++ b/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2019-2022 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +package net.mamoe.mirai.internal.network.protocol.packet.login + +import kotlinx.cinterop.cstr +import sockets.get_ulong_ip_by_name + +internal actual fun String.toIpV4Long(): Long { + return get_ulong_ip_by_name(this.cstr).toLong() +} \ No newline at end of file From aa846a51d7270866b8df6763145cbd3016faea82 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Fri, 18 Nov 2022 02:04:28 +0800 Subject: [PATCH 02/15] Add unit test for ip conversion --- .../protocol.packet.login/IpConversionTest.kt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt diff --git a/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt b/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt new file mode 100644 index 00000000000..e3da38bd70c --- /dev/null +++ b/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2022 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +package net.mamoe.mirai.internal.network.protocol.packet.login + +import net.mamoe.mirai.internal.test.runBlockingUnit +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class IpConversionTest { + @Test + fun `test bad ipAddress`() = runBlockingUnit { + assertEquals(-2, "some^ting%bad".toIpV4Long()) + assertEquals(-2, "another_bad".toIpV4Long()) + assertEquals(-2, " ".toIpV4Long()) + assertEquals(-2, "the..anotherbad......".toIpV4Long()) + assertEquals(-2, "错误的IP地址".toIpV4Long()) + } + + @Test + fun `test empty ipAddress`() = runBlockingUnit { + assertTrue("".toIpV4Long() == 0L) + } + + @Test + fun `test good ipAddress`() = runBlockingUnit { + assertTrue("www.baidu.com".toIpV4Long() > 0) + assertTrue("www.qq.com".toIpV4Long() > 0) + assertTrue("www.sohu.com".toIpV4Long() > 0) + assertTrue("www.weibo.com".toIpV4Long() > 0) + } + + @Test + fun `test plain ipAddress`() = runBlockingUnit { + assertTrue("192.168.1.1".toIpV4Long() == 16885952L) + assertTrue("255.255.255.255".toIpV4Long() == 4294967295L) + assertTrue("0.0.0.0".toIpV4Long() == 0L) + assertTrue("111.111.111.111".toIpV4Long() == 1869573999L) + } +} \ No newline at end of file From a89da692cf345fa7dd61b2b4d55b3e4045396350 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Fri, 18 Nov 2022 03:14:19 +0800 Subject: [PATCH 03/15] Fix bug and add test to unit test --- .../network/protocol.packet.login/IpConversionTest.kt | 9 +++++---- .../kotlin/network/protocol/packet/login/StatSvc.kt | 8 +++++++- .../kotlin/network/protocol/packet/login/StatSvc.kt | 11 ++++++++++- .../kotlin/network/protocol/packet/login/StatSvc.kt | 11 ++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt b/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt index e3da38bd70c..e1eadf4086a 100644 --- a/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt @@ -20,6 +20,7 @@ class IpConversionTest { assertEquals(-2, "some^ting%bad".toIpV4Long()) assertEquals(-2, "another_bad".toIpV4Long()) assertEquals(-2, " ".toIpV4Long()) + assertEquals(-2, "w.a.c.d".toIpV4Long()) assertEquals(-2, "the..anotherbad......".toIpV4Long()) assertEquals(-2, "错误的IP地址".toIpV4Long()) } @@ -39,9 +40,9 @@ class IpConversionTest { @Test fun `test plain ipAddress`() = runBlockingUnit { - assertTrue("192.168.1.1".toIpV4Long() == 16885952L) - assertTrue("255.255.255.255".toIpV4Long() == 4294967295L) - assertTrue("0.0.0.0".toIpV4Long() == 0L) - assertTrue("111.111.111.111".toIpV4Long() == 1869573999L) + assertEquals(16885952L, "192.168.1.1".toIpV4Long()) + assertEquals(4294967295L, "255.255.255.255".toIpV4Long()) + assertEquals(0L, "0.0.0.0".toIpV4Long()) + assertEquals(1869573999L, "111.111.111.111".toIpV4Long()) } } \ No newline at end of file diff --git a/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt index ff50712fb42..aa7cbc38d51 100644 --- a/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -9,6 +9,7 @@ package net.mamoe.mirai.internal.network.protocol.packet.login +import net.mamoe.mirai.utils.mapToByteArray import net.mamoe.mirai.utils.toInt import net.mamoe.mirai.utils.toLongUnsigned import java.net.Inet4Address @@ -19,7 +20,12 @@ internal actual fun String.toIpV4Long(): Long { 0 } else { try { - Inet4Address.getByName(this).address.toInt().toLongUnsigned() + val split = split('.') + return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { + split.reversed().mapToByteArray { + it.toUByte().toByte() + }.toInt().toLongUnsigned() + } else Inet4Address.getByName(this).address.toInt().toLongUnsigned() } catch (e: UnknownHostException) { -2 } diff --git a/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt index c96c0ad7f6e..b8f7116d97f 100644 --- a/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt @@ -10,8 +10,17 @@ package net.mamoe.mirai.internal.network.protocol.packet.login import kotlinx.cinterop.cstr +import net.mamoe.mirai.utils.mapToByteArray +import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.toLongUnsigned import sockets.get_ulong_ip_by_name internal actual fun String.toIpV4Long(): Long { - return get_ulong_ip_by_name(this.cstr).toLong(); + if (isEmpty()) return 0 + val split = split('.') + return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { + split.reversed().mapToByteArray { + it.toUByte().toByte() + }.toInt().toLongUnsigned() + } else get_ulong_ip_by_name(this.cstr).toLong(); } \ No newline at end of file diff --git a/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt index bd1fea17eca..0377db07759 100644 --- a/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -10,8 +10,17 @@ package net.mamoe.mirai.internal.network.protocol.packet.login import kotlinx.cinterop.cstr +import net.mamoe.mirai.utils.mapToByteArray +import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.toLongUnsigned import sockets.get_ulong_ip_by_name internal actual fun String.toIpV4Long(): Long { - return get_ulong_ip_by_name(this.cstr).toLong() + if (isEmpty()) return 0 + val split = split('.') + return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { + split.reversed().mapToByteArray { + it.toUByte().toByte() + }.toInt().toLongUnsigned() + } else get_ulong_ip_by_name(this.cstr).toLong() } \ No newline at end of file From 40516d96bc0b2b198506f8143c7d3c11c2cd705e Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Fri, 18 Nov 2022 04:03:55 +0800 Subject: [PATCH 04/15] Fix offline bid --- .../commonMain/kotlin/network/protocol/packet/login/StatSvc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt index 472cf5d789f..d3cb70e91ae 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -194,7 +194,7 @@ internal class StatSvc { fun offline( client: QQAndroidClient, regPushReason: RegPushReason = RegPushReason.appRegister - ) = impl("offline", client, 1L or 2 or 4, OnlineStatus.OFFLINE, regPushReason) + ) = impl("offline", client, 0, OnlineStatus.OFFLINE, regPushReason) private fun impl( name: String, From 040bc165f348d3fc7f0180d08f1b3fc4fcd3d4b8 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 15:58:58 +0800 Subject: [PATCH 05/15] Refactor to get socket ip directly Fallback to resolve dns when testing --- .../src/commonMain/kotlin/QQAndroidBot.kt | 10 +--- .../kotlin/network/components/ServerList.kt | 8 +-- .../network/handler/CommonNetworkHandler.kt | 6 ++ .../network/protocol/packet/login/StatSvc.kt | 13 ++++- .../commonMain/kotlin/utils/PlatformSocket.kt | 1 + .../network/framework/AbstractCommonNHTest.kt | 12 +++- .../AbstractCommonNHTestWithSelector.kt | 3 +- .../handler/StandaloneSelectorTests.kt | 3 +- .../impl/common/CommonNHAddressChangedTest.kt | 4 +- .../network/impl/netty/NettyNetworkHandler.kt | 12 ++++ .../network/protocol/packet/login/StatSvc.kt | 33 ----------- .../kotlin/utils/PlatformSocket.kt | 7 +++ .../network/framework/AbstractCommonNHTest.kt | 12 +++- .../network/framework/NettyNHTestChannel.kt | 2 +- .../src/mingwX64Main/cinterop/Socket.def | 57 ++++++++++--------- .../network/protocol/packet/login/StatSvc.kt | 26 --------- .../kotlin/utils/PlatformSocket.kt | 6 ++ .../network/handler/NativeNetworkHandler.kt | 6 +- .../network/framework/AbstractCommonNHTest.kt | 23 +++++++- mirai-core/src/unixMain/cinterop/Socket.def | 13 ++++- .../network/protocol/packet/login/StatSvc.kt | 26 --------- .../unixMain/kotlin/utils/PlatformSocket.kt | 7 +++ 22 files changed, 149 insertions(+), 141 deletions(-) delete mode 100644 mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt delete mode 100644 mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt delete mode 100644 mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt index ce2c3b5fddf..bd26c7edb66 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt +++ b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt @@ -22,11 +22,8 @@ import net.mamoe.mirai.internal.network.component.ComponentStorageDelegate import net.mamoe.mirai.internal.network.component.ConcurrentComponentStorage import net.mamoe.mirai.internal.network.component.withFallback import net.mamoe.mirai.internal.network.components.* -import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.* import net.mamoe.mirai.internal.network.handler.NetworkHandler.State -import net.mamoe.mirai.internal.network.handler.NetworkHandlerContextImpl -import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory -import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.BaseStateImpl import net.mamoe.mirai.internal.network.handler.selector.KeepAliveNetworkHandlerSelector import net.mamoe.mirai.internal.network.handler.selector.NetworkException @@ -123,11 +120,6 @@ internal open class QQAndroidBot constructor( override fun toString(): String = "StateChangedObserver(BotOnlineEventBroadcaster)" }, - StateChangedObserver("LastConnectedAddressUpdater", State.OK) { - components[ServerList].run { - lastConnectedIP = getLastPolledIP() - } - }, StateChangedObserver("LastDisconnectedAddressUpdater", State.CLOSED) { components[ServerList].run { lastDisconnectedIP = lastConnectedIP diff --git a/mirai-core/src/commonMain/kotlin/network/components/ServerList.kt b/mirai-core/src/commonMain/kotlin/network/components/ServerList.kt index 3ac61a74f59..f71a12c747f 100644 --- a/mirai-core/src/commonMain/kotlin/network/components/ServerList.kt +++ b/mirai-core/src/commonMain/kotlin/network/components/ServerList.kt @@ -64,12 +64,12 @@ internal interface ServerList { /** * Last disconnected ip */ - var lastDisconnectedIP: String + var lastDisconnectedIP: Long /** * Last connected ip */ - var lastConnectedIP: String + var lastConnectedIP: Long /** * Get last poll ip @@ -139,8 +139,8 @@ internal class ServerListImpl( } } - override var lastDisconnectedIP: String = "" - override var lastConnectedIP: String = "" + override var lastDisconnectedIP: Long = 0L + override var lastConnectedIP: Long = 0L override fun getLastPolledIP(): String = lastPolledAddress?.host ?: "" diff --git a/mirai-core/src/commonMain/kotlin/network/handler/CommonNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/CommonNetworkHandler.kt index 4d5dfbb8800..7a71104e285 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/CommonNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/CommonNetworkHandler.kt @@ -94,6 +94,11 @@ internal abstract class CommonNetworkHandler( @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "KotlinRedundantDiagnosticSuppress") // can happen on some platforms protected abstract fun Conn.close() + /** + * Get the connected ip in network order + */ + protected abstract fun Conn.getConnectedIP(): Long + /** * *Single-thread* event-loop packet decoder. * @@ -244,6 +249,7 @@ internal abstract class CommonNetworkHandler( connection.join() try { context[SsoProcessor].login(this@CommonNetworkHandler) + context[ServerList].lastConnectedIP = connection.await().getConnectedIP() } catch (e: LoginFailedException) { throw LoginFailedExceptionAsNetworkException(e) } diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt index d3cb70e91ae..831f4c506d6 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/StatSvc.kt @@ -169,8 +169,16 @@ internal class StatSvc { if (client.bot.configuration.protocol == BotConfiguration.MiraiProtocol.ANDROID_PHONE) { client.bot.components[ServerList].run { kotlin.runCatching { - uOldSSOIp = lastDisconnectedIP.toIpV4Long() - uNewSSOIp = lastConnectedIP.toIpV4Long() + uOldSSOIp = if (lastDisconnectedIP in 1..2) { + -lastDisconnectedIP + } else { + lastDisconnectedIP + } + uNewSSOIp = if (lastConnectedIP in 1..2) { + -lastDisconnectedIP + } else { + lastConnectedIP + } }.onFailure { err -> client.bot.network.logger.warning({ "Exception when converting ipaddress to long: ld=${lastDisconnectedIP}, lc=${lastConnectedIP}" @@ -425,4 +433,3 @@ internal class StatSvc { } } -internal expect fun String.toIpV4Long(): Long diff --git a/mirai-core/src/commonMain/kotlin/utils/PlatformSocket.kt b/mirai-core/src/commonMain/kotlin/utils/PlatformSocket.kt index 985b47d57ad..80cec778202 100644 --- a/mirai-core/src/commonMain/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/commonMain/kotlin/utils/PlatformSocket.kt @@ -24,6 +24,7 @@ import kotlin.jvm.JvmName */ internal expect class PlatformSocket : Closeable, HighwayProtocolChannel { val isOpen: Boolean + val connectedIp: Long override fun close() diff --git a/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTest.kt b/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTest.kt index 3ff229f6df7..e150929efaa 100644 --- a/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTest.kt @@ -25,7 +25,11 @@ internal abstract class TestCommonNetworkHandler( address: SocketAddress, ) : CommonNetworkHandler(context, address), ITestNetworkHandler { override suspend fun createConnection(): PlatformConn { - return PlatformConn() + return PlatformConn(address) + } + + override fun PlatformConn.getConnectedIP(): Long { + return getConnectedIPPlatform() } override fun PlatformConn.writeAndFlushOrCloseAsync(packet: OutgoingPacket) { @@ -104,4 +108,8 @@ internal expect abstract class AbstractCommonNHTest() : protected fun removeOutgoingPacketEncoder() } -internal expect class PlatformConn() \ No newline at end of file +internal expect class PlatformConn(address: SocketAddress) { + val address: SocketAddress + internal fun getConnectedIPPlatform(): Long + +} \ No newline at end of file diff --git a/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt b/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt index 6955af4c73b..e0a4189b757 100644 --- a/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt +++ b/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt @@ -30,7 +30,7 @@ internal abstract class AbstractCommonNHTestWithSelector : overrideComponents[BotOfflineEventMonitor] = BotOfflineEventMonitorImpl() } - val conn = PlatformConn() + val conn = PlatformConn(address) val selector = TestSelector { object : TestCommonNetworkHandler(bot, createContext(), createAddress()) { @@ -38,6 +38,7 @@ internal abstract class AbstractCommonNHTestWithSelector : override suspend fun createConnection(): PlatformConn { return conn } + } } diff --git a/mirai-core/src/commonTest/kotlin/network/handler/StandaloneSelectorTests.kt b/mirai-core/src/commonTest/kotlin/network/handler/StandaloneSelectorTests.kt index c1bfcb97432..045ab1536da 100644 --- a/mirai-core/src/commonTest/kotlin/network/handler/StandaloneSelectorTests.kt +++ b/mirai-core/src/commonTest/kotlin/network/handler/StandaloneSelectorTests.kt @@ -9,7 +9,6 @@ package net.mamoe.mirai.internal.network.handler -import kotlinx.atomicfu.atomic import net.mamoe.mirai.internal.network.components.FirstLoginResult import net.mamoe.mirai.internal.network.components.SsoProcessor import net.mamoe.mirai.internal.network.framework.AbstractCommonNHTest @@ -41,7 +40,7 @@ internal class StandaloneSelectorTests : AbstractCommonNHTest() { NetworkHandlerFactory { context, address -> object : TestCommonNetworkHandler(bot, context, address) { override suspend fun createConnection(): PlatformConn { - return throwExceptionOnConnecting?.invoke() ?: PlatformConn() + return throwExceptionOnConnecting?.invoke() ?: PlatformConn(address) } } } diff --git a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHAddressChangedTest.kt b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHAddressChangedTest.kt index 34967e99ae0..bf47772c577 100644 --- a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHAddressChangedTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHAddressChangedTest.kt @@ -25,8 +25,8 @@ internal class CommonNHAddressChangedTest : AbstractCommonNHTest() { networkLogger.debug("before login, Assuming both ip is empty") val lastConnectedIpOld = bot.components[ServerList].lastConnectedIP val lastDisconnectedIpOld = bot.components[ServerList].lastDisconnectedIP - assertTrue(lastConnectedIpOld.isEmpty(), "Assuming lastConnectedIp is empty") - assertTrue(lastDisconnectedIpOld.isEmpty(), "Assuming lastDisconnectedIp is empty") + assertTrue(lastConnectedIpOld == 0L, "Assuming lastConnectedIp is empty") + assertTrue(lastDisconnectedIpOld == 0L, "Assuming lastDisconnectedIp is empty") networkLogger.debug("Do login, Assuming lastConnectedIp is NOT empty") bot.login() diff --git a/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt b/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt index 04909eb0f43..2de31f99475 100644 --- a/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt +++ b/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt @@ -26,6 +26,8 @@ import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.utils.cast import net.mamoe.mirai.utils.debug +import net.mamoe.mirai.utils.toInt +import java.net.InetSocketAddress import java.net.SocketAddress import io.netty.channel.Channel as NettyChannel @@ -131,6 +133,16 @@ internal open class NettyNetworkHandler( return contextResult.await() } + override fun Channel.getConnectedIP(): Long = this.remoteAddress().let { address -> + { + if (this.isOpen && address is InetSocketAddress) { + address.address.address.copyOf().also { it.reverse() }.toInt().toLong() + } else { + 0L + } + } + }.invoke() + @Suppress("EXTENSION_SHADOWED_BY_MEMBER") override fun io.netty.channel.Channel.close() { this.close() diff --git a/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt deleted file mode 100644 index aa7cbc38d51..00000000000 --- a/mirai-core/src/jvmBaseMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2019-2022 Mamoe Technologies and contributors. - * - * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. - * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. - * - * https://github.com/mamoe/mirai/blob/dev/LICENSE - */ - -package net.mamoe.mirai.internal.network.protocol.packet.login - -import net.mamoe.mirai.utils.mapToByteArray -import net.mamoe.mirai.utils.toInt -import net.mamoe.mirai.utils.toLongUnsigned -import java.net.Inet4Address -import java.net.UnknownHostException - -internal actual fun String.toIpV4Long(): Long { - return if (isEmpty()) { - 0 - } else { - try { - val split = split('.') - return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { - split.reversed().mapToByteArray { - it.toUByte().toByte() - }.toInt().toLongUnsigned() - } else Inet4Address.getByName(this).address.toInt().toLongUnsigned() - } catch (e: UnknownHostException) { - -2 - } - } -} \ No newline at end of file diff --git a/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt b/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt index d484f97daaf..60a8109031e 100644 --- a/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.suspendCancellableCoroutine import net.mamoe.mirai.internal.network.highway.HighwayProtocolChannel +import net.mamoe.mirai.utils.toInt import java.io.BufferedInputStream import java.io.BufferedOutputStream import java.io.IOException @@ -31,6 +32,12 @@ internal actual class PlatformSocket : Closeable, HighwayProtocolChannel { if (::socket.isInitialized) socket.isConnected else false + actual val connectedIp: Long + get() = if (isOpen) { + socket.inetAddress.address.copyOf().also { it.reverse() }.toInt().toLong() + } else { + 0L + } actual override fun close() { if (::socket.isInitialized) { diff --git a/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt b/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt index cb30348bfc1..71435be9ad6 100644 --- a/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt +++ b/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt @@ -11,6 +11,9 @@ package net.mamoe.mirai.internal.network.framework import kotlinx.coroutines.ExecutorCoroutineDispatcher import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory +import net.mamoe.mirai.internal.network.handler.SocketAddress +import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.toLongUnsigned import kotlin.test.AfterTest /** @@ -51,7 +54,12 @@ internal actual abstract class AbstractCommonNHTest actual constructor() : } } - actual val conn: PlatformConn = NettyNHTestChannel() + actual val conn: PlatformConn get() = PlatformConn(address = createAddress()) +} + +internal actual class PlatformConn actual constructor(actual val address: SocketAddress) : NettyNHTestChannel() { + actual fun getConnectedIPPlatform(): Long { + return address.address.address.copyOf().also { it.reverse() }.toInt().toLongUnsigned() + } } -internal actual typealias PlatformConn = NettyNHTestChannel diff --git a/mirai-core/src/jvmBaseTest/kotlin/network/framework/NettyNHTestChannel.kt b/mirai-core/src/jvmBaseTest/kotlin/network/framework/NettyNHTestChannel.kt index 6636c936f67..c2c9117fc77 100644 --- a/mirai-core/src/jvmBaseTest/kotlin/network/framework/NettyNHTestChannel.kt +++ b/mirai-core/src/jvmBaseTest/kotlin/network/framework/NettyNHTestChannel.kt @@ -23,7 +23,7 @@ import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.cast import net.mamoe.mirai.utils.error -internal class NettyNHTestChannel( +internal sealed class NettyNHTestChannel( var fakeServer: (NettyNHTestChannel.(msg: Any?) -> Unit)?, ) : EmbeddedChannel() { constructor() : this(null) diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index 45389713c9d..29fcb9dc1be 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -21,35 +21,40 @@ static unsigned long get_ulong_ip_by_name(char* host) { return result; } else { - return -2; + return 2; } } -static SOCKET socket_create_connect(char *host, unsigned short port) { - SOCKADDR_STORAGE local_addr = {0}; - SOCKADDR_STORAGE remote_addr = {0}; - DWORD local_addr_size = sizeof(local_addr); - DWORD remote_addr_size = sizeof(remote_addr); - char port_name[6]; - int sockfd; +static unsigned long socket_get_connected_ip(int sockfd) { + struct sockaddr_in peer_addr; + int peer_addr_size = sizeof(peer_addr); + if (!(sockfd > 0)) { + return 1; + } + if (getpeername(sockfd, (SOCKADDR*)&peer_addr, &peer_addr_size) == 0) { + return peer_addr.sin_addr.s_addr; + } + return 2; +} - sprintf(port_name, "%d", (int)port); +static SOCKET socket_create_connect(char* host, char* port_name) { + SOCKADDR_STORAGE local_addr = { 0 }; + SOCKADDR_STORAGE remote_addr = { 0 }; + DWORD local_addr_size = sizeof(local_addr); + DWORD remote_addr_size = sizeof(remote_addr); + int sockfd; - if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == INVALID_SOCKET) { - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { - return INVALID_SOCKET; - } - } else { - int ipv6only = 0; - setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only)); - } - if (!WSAConnectByNameA(sockfd, host, port_name, &local_addr_size, (SOCKADDR*)&local_addr, &remote_addr_size, (SOCKADDR*)&remote_addr, NULL, NULL)) { - closesocket(sockfd); - return INVALID_SOCKET; - } - if (setsockopt(sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == SOCKET_ERROR) { - closesocket(sockfd); - return INVALID_SOCKET; - } - return sockfd; + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { + return INVALID_SOCKET; + } + if (!WSAConnectByNameA(sockfd, host, port_name, &local_addr_size, (SOCKADDR*)&local_addr, &remote_addr_size, (SOCKADDR*)&remote_addr, NULL, NULL)) { + closesocket(sockfd); + return INVALID_SOCKET; + } + + if (setsockopt(sockfd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == SOCKET_ERROR) { + closesocket(sockfd); + return INVALID_SOCKET; + } + return sockfd; } \ No newline at end of file diff --git a/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt deleted file mode 100644 index b8f7116d97f..00000000000 --- a/mirai-core/src/mingwX64Main/kotlin/network/protocol/packet/login/StatSvc.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2019-2022 Mamoe Technologies and contributors. - * - * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. - * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. - * - * https://github.com/mamoe/mirai/blob/dev/LICENSE - */ - -package net.mamoe.mirai.internal.network.protocol.packet.login - -import kotlinx.cinterop.cstr -import net.mamoe.mirai.utils.mapToByteArray -import net.mamoe.mirai.utils.toInt -import net.mamoe.mirai.utils.toLongUnsigned -import sockets.get_ulong_ip_by_name - -internal actual fun String.toIpV4Long(): Long { - if (isEmpty()) return 0 - val split = split('.') - return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { - split.reversed().mapToByteArray { - it.toUByte().toByte() - }.toInt().toLongUnsigned() - } else get_ulong_ip_by_name(this.cstr).toLong(); -} \ No newline at end of file diff --git a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt index c5842029772..95e0748a607 100644 --- a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt @@ -43,6 +43,12 @@ internal actual class PlatformSocket( actual val isOpen: Boolean get() = send(socket, null, 0, 0).convert() != 0L + actual val connectedIp: Long + get() = if (isOpen) { + sockets.socket_get_connected_ip(socket) + } else { + 0L + } actual override fun close() { closesocket(socket) diff --git a/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt b/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt index 599d40711c3..d9586bb9f6a 100644 --- a/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt +++ b/mirai-core/src/nativeMain/kotlin/network/handler/NativeNetworkHandler.kt @@ -36,7 +36,7 @@ internal class NativeNetworkHandler( } internal inner class NativeConn( - private val socket: PlatformSocket, + internal val socket: PlatformSocket, ) : Closeable, CoroutineScope by coroutineContext.childScope("NativeConn") { private val decodePipeline: PacketDecodePipeline = PacketDecodePipeline(this.coroutineContext) @@ -102,6 +102,10 @@ internal class NativeNetworkHandler( } } + override fun NativeConn.getConnectedIP(): Long { + return this.socket.connectedIp + } + @Suppress("EXTENSION_SHADOWED_BY_MEMBER") override fun NativeConn.close() { this.close() diff --git a/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt b/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt index fa0e6fc9f9f..2b13b219324 100644 --- a/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt +++ b/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt @@ -9,7 +9,12 @@ package net.mamoe.mirai.internal.network.framework +import kotlinx.cinterop.cstr import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory +import net.mamoe.mirai.internal.network.handler.SocketAddress +import net.mamoe.mirai.utils.mapToByteArray +import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.toLongUnsigned /** * Without selector. When network is closed, it will not reconnect, so that you can check for its states. @@ -32,8 +37,22 @@ internal actual abstract class AbstractCommonNHTest actual constructor() : protected actual fun removeOutgoingPacketEncoder() { } - actual val conn: PlatformConn = PlatformConn() + actual val conn: PlatformConn get() = PlatformConn(createAddress()) } -internal actual class PlatformConn \ No newline at end of file +internal actual class PlatformConn actual constructor(actual val address: SocketAddress) { + internal actual fun getConnectedIPPlatform(): Long { + address.host.run { + if (isEmpty()) return 0 + val split = split('.') + return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { + split.reversed().mapToByteArray { + it.toUByte().toByte() + }.toInt().toLongUnsigned() + } else sockets.get_ulong_ip_by_name(this.cstr).toLong(); + } + } + + +} \ No newline at end of file diff --git a/mirai-core/src/unixMain/cinterop/Socket.def b/mirai-core/src/unixMain/cinterop/Socket.def index b861820299f..09c8d541278 100644 --- a/mirai-core/src/unixMain/cinterop/Socket.def +++ b/mirai-core/src/unixMain/cinterop/Socket.def @@ -25,7 +25,18 @@ static unsigned long get_ulong_ip_by_name(char* host) { } } } - return -2; + return 2; +} + +static unsigned long socket_get_connected_ip(int sockfd) { + struct sockaddr_in peer_addr; + if (!(sockfd > 0)) { + return 1; + } + if (!getpeername(sockfd, (struct sockaddr*)&peer_addr, sizeof(peer_addr))) { + return peer_addr.sin_addr.s_addr; + } + return 2; } static int socket_create_connect(char *host, ushort port) { diff --git a/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt b/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt deleted file mode 100644 index 0377db07759..00000000000 --- a/mirai-core/src/unixMain/kotlin/network/protocol/packet/login/StatSvc.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2019-2022 Mamoe Technologies and contributors. - * - * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. - * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. - * - * https://github.com/mamoe/mirai/blob/dev/LICENSE - */ - -package net.mamoe.mirai.internal.network.protocol.packet.login - -import kotlinx.cinterop.cstr -import net.mamoe.mirai.utils.mapToByteArray -import net.mamoe.mirai.utils.toInt -import net.mamoe.mirai.utils.toLongUnsigned -import sockets.get_ulong_ip_by_name - -internal actual fun String.toIpV4Long(): Long { - if (isEmpty()) return 0 - val split = split('.') - return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { - split.reversed().mapToByteArray { - it.toUByte().toByte() - }.toInt().toLongUnsigned() - } else get_ulong_ip_by_name(this.cstr).toLong() -} \ No newline at end of file diff --git a/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt b/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt index f0d317923eb..32e96c6475e 100644 --- a/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt @@ -23,6 +23,7 @@ import platform.posix.close import platform.posix.errno import platform.posix.recv import platform.posix.write +import sockets.socket_get_connected_ip import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -48,6 +49,12 @@ internal actual class PlatformSocket( actual val isOpen: Boolean get() = write(socket, null, 0).convert() != 0L + actual val connectedIp: Long + get() = if (isOpen) { + socket_get_connected_ip(socket) + } else { + 0L + } actual override fun close() { close(socket) From 68a495893780d9004a1aaa6f46dd81aeed304892 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 16:07:24 +0800 Subject: [PATCH 06/15] Fix bug in getConnectedIPPlatform Using all instead of any --- .../nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt b/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt index 2b13b219324..ab1a1fd16ea 100644 --- a/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt +++ b/mirai-core/src/nativeTest/kotlin/network/framework/AbstractCommonNHTest.kt @@ -46,7 +46,7 @@ internal actual class PlatformConn actual constructor(actual val address: Socket address.host.run { if (isEmpty()) return 0 val split = split('.') - return if (split.size == 4 && split.any { it.toUByteOrNull() != null }) { + return if (split.size == 4 && split.all { it.toUByteOrNull() != null }) { split.reversed().mapToByteArray { it.toUByte().toByte() }.toInt().toLongUnsigned() From 54cd19b56b1c00d0b3e9372f2443a5de33c731f8 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 16:20:29 +0800 Subject: [PATCH 07/15] Fix build --- mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt | 3 ++- mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt index 95e0748a607..7337690c44e 100644 --- a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt @@ -21,6 +21,7 @@ import net.mamoe.mirai.utils.ByteArrayPool import net.mamoe.mirai.utils.DEFAULT_BUFFER_SIZE import net.mamoe.mirai.utils.toReadPacket import platform.posix.* +import sockets.socket_get_connected_ip import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -45,7 +46,7 @@ internal actual class PlatformSocket( get() = send(socket, null, 0, 0).convert() != 0L actual val connectedIp: Long get() = if (isOpen) { - sockets.socket_get_connected_ip(socket) + sockets.socket_get_connected_ip(socket).toLong() } else { 0L } diff --git a/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt b/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt index 32e96c6475e..e453280c3c4 100644 --- a/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/unixMain/kotlin/utils/PlatformSocket.kt @@ -51,7 +51,7 @@ internal actual class PlatformSocket( get() = write(socket, null, 0).convert() != 0L actual val connectedIp: Long get() = if (isOpen) { - socket_get_connected_ip(socket) + socket_get_connected_ip(socket).toLong() } else { 0L } From 0fb8886365235e5af2e23d67ebf6d722b15e9fe2 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 16:45:19 +0800 Subject: [PATCH 08/15] Fix unit test --- .../test/PlatformSocketIpTest.kt} | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) rename mirai-core/src/commonTest/kotlin/network/{protocol.packet.login/IpConversionTest.kt => framework/test/PlatformSocketIpTest.kt} (77%) diff --git a/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt b/mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt similarity index 77% rename from mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt rename to mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt index e1eadf4086a..570e8426b98 100644 --- a/mirai-core/src/commonTest/kotlin/network/protocol.packet.login/IpConversionTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt @@ -7,14 +7,26 @@ * https://github.com/mamoe/mirai/blob/dev/LICENSE */ -package net.mamoe.mirai.internal.network.protocol.packet.login +package net.mamoe.mirai.internal.network.framework.test +import net.mamoe.mirai.internal.network.framework.PlatformConn +import net.mamoe.mirai.internal.network.handler.createSocketAddress import net.mamoe.mirai.internal.test.runBlockingUnit import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue class IpConversionTest { + private fun String.toIpV4Long(): Long { + PlatformConn(address = createSocketAddress(host = this, port = 80)).getConnectedIPPlatform().run { + return if (this in 1..2) { + -this + } else { + this + } + } + } + @Test fun `test bad ipAddress`() = runBlockingUnit { assertEquals(-2, "some^ting%bad".toIpV4Long()) From e831be605ee8794a702b2daae3bd84b92f357b0f Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 16:54:42 +0800 Subject: [PATCH 09/15] Fix build --- .../kotlin/network/impl/netty/NettyNetworkHandler.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt b/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt index 2de31f99475..910eef91bc3 100644 --- a/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt +++ b/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt @@ -133,7 +133,7 @@ internal open class NettyNetworkHandler( return contextResult.await() } - override fun Channel.getConnectedIP(): Long = this.remoteAddress().let { address -> + override fun io.netty.channel.Channel.getConnectedIP(): Long = this.remoteAddress().let { address -> { if (this.isOpen && address is InetSocketAddress) { address.address.address.copyOf().also { it.reverse() }.toInt().toLong() From 6a076174099cdecedc5ff5fe92e93e1d0ff2e87c Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 17:46:54 +0800 Subject: [PATCH 10/15] Fix unit test and build --- .../framework/AbstractCommonNHTestWithSelector.kt | 2 +- .../network/framework/test/PlatformSocketIpTest.kt | 5 ----- .../kotlin/network/impl/netty/NettyNetworkHandler.kt | 8 +++----- .../src/jvmBaseMain/kotlin/utils/PlatformSocket.kt | 3 ++- .../kotlin/network/framework/AbstractCommonNHTest.kt | 9 ++++++++- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt b/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt index e0a4189b757..fc6d30fe98c 100644 --- a/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt +++ b/mirai-core/src/commonTest/kotlin/network/framework/AbstractCommonNHTestWithSelector.kt @@ -30,7 +30,7 @@ internal abstract class AbstractCommonNHTestWithSelector : overrideComponents[BotOfflineEventMonitor] = BotOfflineEventMonitorImpl() } - val conn = PlatformConn(address) + val conn get() = PlatformConn(createAddress()) val selector = TestSelector { object : TestCommonNetworkHandler(bot, createContext(), createAddress()) { diff --git a/mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt b/mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt index 570e8426b98..88f899e2d48 100644 --- a/mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/framework/test/PlatformSocketIpTest.kt @@ -37,11 +37,6 @@ class IpConversionTest { assertEquals(-2, "错误的IP地址".toIpV4Long()) } - @Test - fun `test empty ipAddress`() = runBlockingUnit { - assertTrue("".toIpV4Long() == 0L) - } - @Test fun `test good ipAddress`() = runBlockingUnit { assertTrue("www.baidu.com".toIpV4Long() > 0) diff --git a/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt b/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt index 910eef91bc3..7fccc6c78c0 100644 --- a/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt +++ b/mirai-core/src/jvmBaseMain/kotlin/network/impl/netty/NettyNetworkHandler.kt @@ -24,9 +24,7 @@ import net.mamoe.mirai.internal.network.handler.CommonNetworkHandler import net.mamoe.mirai.internal.network.handler.NetworkHandler.State import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket -import net.mamoe.mirai.utils.cast -import net.mamoe.mirai.utils.debug -import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.* import java.net.InetSocketAddress import java.net.SocketAddress import io.netty.channel.Channel as NettyChannel @@ -135,8 +133,8 @@ internal open class NettyNetworkHandler( override fun io.netty.channel.Channel.getConnectedIP(): Long = this.remoteAddress().let { address -> { - if (this.isOpen && address is InetSocketAddress) { - address.address.address.copyOf().also { it.reverse() }.toInt().toLong() + if (this.isActive && address is InetSocketAddress) { + address.address?.address?.copyOf()?.also { it.reverse() }?.toInt()?.toLongUnsigned() ?: 2L } else { 0L } diff --git a/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt b/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt index 60a8109031e..96ab9baaa04 100644 --- a/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.suspendCancellableCoroutine import net.mamoe.mirai.internal.network.highway.HighwayProtocolChannel import net.mamoe.mirai.utils.toInt +import net.mamoe.mirai.utils.toLongUnsigned import java.io.BufferedInputStream import java.io.BufferedOutputStream import java.io.IOException @@ -34,7 +35,7 @@ internal actual class PlatformSocket : Closeable, HighwayProtocolChannel { else false actual val connectedIp: Long get() = if (isOpen) { - socket.inetAddress.address.copyOf().also { it.reverse() }.toInt().toLong() + socket.inetAddress.address?.copyOf()?.also { it.reverse() }?.toInt()?.toLongUnsigned() ?: 2L } else { 0L } diff --git a/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt b/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt index 71435be9ad6..8e19a82c7be 100644 --- a/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt +++ b/mirai-core/src/jvmBaseTest/kotlin/network/framework/AbstractCommonNHTest.kt @@ -12,8 +12,11 @@ package net.mamoe.mirai.internal.network.framework import kotlinx.coroutines.ExecutorCoroutineDispatcher import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory import net.mamoe.mirai.internal.network.handler.SocketAddress +import net.mamoe.mirai.internal.network.handler.getHost import net.mamoe.mirai.utils.toInt import net.mamoe.mirai.utils.toLongUnsigned +import java.net.InetAddress +import java.net.UnknownHostException import kotlin.test.AfterTest /** @@ -59,7 +62,11 @@ internal actual abstract class AbstractCommonNHTest actual constructor() : internal actual class PlatformConn actual constructor(actual val address: SocketAddress) : NettyNHTestChannel() { actual fun getConnectedIPPlatform(): Long { - return address.address.address.copyOf().also { it.reverse() }.toInt().toLongUnsigned() + return (address.address ?: try { + InetAddress.getByName(address.getHost()) + } catch (e: UnknownHostException) { + null + })?.address?.copyOf()?.also { it.reverse() }?.toInt()?.toLongUnsigned() ?: 2L } } From df762cec827416d8bc56405ec85680d0d059dd03 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 19:22:37 +0800 Subject: [PATCH 11/15] Fix build --- mirai-core/src/mingwX64Main/cinterop/Socket.def | 2 +- mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index 29fcb9dc1be..c6f58631bad 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -25,7 +25,7 @@ static unsigned long get_ulong_ip_by_name(char* host) { } } -static unsigned long socket_get_connected_ip(int sockfd) { +static unsigned long socket_get_connected_ip(SOCKET sockfd) { struct sockaddr_in peer_addr; int peer_addr_size = sizeof(peer_addr); if (!(sockfd > 0)) { diff --git a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt index 7337690c44e..04fb647aaf4 100644 --- a/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt +++ b/mirai-core/src/mingwX64Main/kotlin/utils/PlatformSocket.kt @@ -111,7 +111,7 @@ internal actual class PlatformSocket( serverIp: String, serverPort: Int ): PlatformSocket { - val r = sockets.socket_create_connect(serverIp.cstr, serverPort.toUShort()) + val r = sockets.socket_create_connect(serverIp.cstr, serverPort.toString().cstr) if (r == INVALID_SOCKET) error("Failed socket_create_connect: $r") return PlatformSocket(r) } From fe8b1c9010619b6da9f801584bd3fe33d5bbe673 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 20:05:13 +0800 Subject: [PATCH 12/15] Add ws2_32.lib to linker --- mirai-core/src/mingwX64Main/cinterop/Socket.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index c6f58631bad..dba62ae9cd3 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -1,5 +1,7 @@ headers = winsock.h +linkerOpts = -LWS2_32 + --- #define WIN32_LEAN_AND_MEAN #include From e5707ed3c754bf62c2344551b916026d9b7334ce Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 20:09:11 +0800 Subject: [PATCH 13/15] Add Dnsapi to linker --- mirai-core/src/mingwX64Main/cinterop/Socket.def | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index dba62ae9cd3..14fb3a2ddc2 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -1,6 +1,7 @@ headers = winsock.h -linkerOpts = -LWS2_32 +linkerOpts = -LWS2_32\ + -LDnsapi --- #define WIN32_LEAN_AND_MEAN From b91e4e5caa88b79176d0d6481e546802a614ac5f Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 20:56:39 +0800 Subject: [PATCH 14/15] Try to use -l instead of -L --- mirai-core/src/mingwX64Main/cinterop/Socket.def | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index 14fb3a2ddc2..6de76644433 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -1,7 +1,7 @@ headers = winsock.h -linkerOpts = -LWS2_32\ - -LDnsapi +linkerOpts = -lWS2_32\ + -lDnsapi --- #define WIN32_LEAN_AND_MEAN From 7a61f049679c81aa74e51a2d47bc48477fb4ed28 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Tue, 6 Dec 2022 21:59:48 +0800 Subject: [PATCH 15/15] Fix missed space in linked opts --- mirai-core/src/mingwX64Main/cinterop/Socket.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirai-core/src/mingwX64Main/cinterop/Socket.def b/mirai-core/src/mingwX64Main/cinterop/Socket.def index 6de76644433..75767016333 100644 --- a/mirai-core/src/mingwX64Main/cinterop/Socket.def +++ b/mirai-core/src/mingwX64Main/cinterop/Socket.def @@ -1,6 +1,6 @@ headers = winsock.h -linkerOpts = -lWS2_32\ +linkerOpts = -lWS2_32 \ -lDnsapi ---