Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor StatSvc ip recording, fix #2349 #2351

Draft
wants to merge 16 commits into
base: dev
Choose a base branch
from
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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, "w.a.c.d".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 {
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())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 }) {
sandtechnology marked this conversation as resolved.
Show resolved Hide resolved
split.reversed().mapToByteArray {
it.toUByte().toByte()
}.toInt().toLongUnsigned()
} else Inet4Address.getByName(this).address.toInt().toLongUnsigned()
} catch (e: UnknownHostException) {
-2
}
}
}
17 changes: 17 additions & 0 deletions mirai-core/src/mingwX64Main/cinterop/Socket.def
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ headers = winsock.h
#include <mswsock.h>
#include <stdlib.h>
#include <string.h>
#include <windns.h>

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};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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();
}
22 changes: 22 additions & 0 deletions mirai-core/src/unixMain/cinterop/Socket.def
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@ headers = netdb.h
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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()
}