diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 9b34f35..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -punchnet \ No newline at end of file diff --git a/app/src/main/java/com/jihe/punchnet/PunchnetService.kt b/app/src/main/java/com/jihe/punchnet/PunchnetService.kt index 109f582..f36af04 100644 --- a/app/src/main/java/com/jihe/punchnet/PunchnetService.kt +++ b/app/src/main/java/com/jihe/punchnet/PunchnetService.kt @@ -31,6 +31,7 @@ import com.jihe.punchnet.sdlan.network.run_sdlan import com.jihe.punchnet.sdlan.utils.ipToString import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -49,7 +50,7 @@ class PunchnetService : VpnService() , IfaceTun { var input: FileInputStream? = null var output: FileOutputStream? = null - override val arpTable = ARPTable() + override val arpTable = ARPTable(scope) override val arpWaitList = ARPWaitList() var config: DeviceConfig = DeviceConfig(1400) @@ -62,18 +63,22 @@ class PunchnetService : VpnService() , IfaceTun { override suspend fun recv(): ByteArray { val result = withContext(Dispatchers.IO) { val result = ByteArray(1500) - var size = input?.read(result) - if (size == null) { - println("xxx failed to read") - size = 0 - } else { - println("xxx got $size bytes") - } + try { + var size = input?.read(result) + if (size == null) { + println("xxx failed to read") + size = 0 + } else { + println("xxx got $size bytes") + } - // val size = input?.read(result)?:0 - // Log.d(TAG, "RECEIVED $size bytes") - result.copyOf(size) - // result.slice(0..() suspend fun agingARP() { - CoroutineScope(Dispatchers.Default).async { + // CoroutineScope(Dispatchers.Default).async { + scope.async { while(true) { delay(20_000) val now = System.currentTimeMillis()/1000 diff --git a/app/src/main/java/com/jihe/punchnet/sdlan/network/helper.kt b/app/src/main/java/com/jihe/punchnet/sdlan/network/helper.kt index f90f564..739c4f0 100644 --- a/app/src/main/java/com/jihe/punchnet/sdlan/network/helper.kt +++ b/app/src/main/java/com/jihe/punchnet/sdlan/network/helper.kt @@ -15,11 +15,13 @@ import com.jihe.punchnet.sdlan.utils.macToString import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async +import kotlinx.coroutines.launch import java.nio.ByteBuffer import java.nio.ByteOrder suspend fun handlePacketData( + scope: CoroutineScope, node: Node, body: ByteBuffer, senderSock: SDLanSock @@ -36,7 +38,8 @@ suspend fun handlePacketData( TerminalLogger.debugf { "[P2P] Rx data from ${senderSock}" } - CoroutineScope(Dispatchers.Default).async { + // CoroutineScope(Dispatchers.Default).async { + scope.async { checkPeerRegistrationNeeded( node, false, diff --git a/app/src/main/java/com/jihe/punchnet/sdlan/network/iface.kt b/app/src/main/java/com/jihe/punchnet/sdlan/network/iface.kt index bc019aa..c9ed408 100644 --- a/app/src/main/java/com/jihe/punchnet/sdlan/network/iface.kt +++ b/app/src/main/java/com/jihe/punchnet/sdlan/network/iface.kt @@ -11,6 +11,7 @@ import com.jihe.punchnet.sdlan.utils.EthHdr import com.jihe.punchnet.sdlan.utils.ipToString import com.jihe.punchnet.sdlan.utils.isMultiBroadcast import com.jihe.punchnet.sdlan.utils.macToString +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.BufferedReader @@ -216,7 +217,7 @@ interface IfaceTun: Iface { class IfaceMock: IfaceTun { val deviceName = "dev0" - override val arpTable = ARPTable() + override val arpTable = ARPTable(CoroutineScope(Dispatchers.IO)) override val arpWaitList = ARPWaitList() val sock = Socket(Inet4Address.getByName("127.0.0.1"), 1234) diff --git a/app/src/main/java/com/jihe/punchnet/sdlan/network/libs.kt b/app/src/main/java/com/jihe/punchnet/sdlan/network/libs.kt index dbe3ac4..8e5ddad 100644 --- a/app/src/main/java/com/jihe/punchnet/sdlan/network/libs.kt +++ b/app/src/main/java/com/jihe/punchnet/sdlan/network/libs.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import java.io.DataInputStream @@ -40,7 +41,7 @@ import java.util.concurrent.atomic.AtomicLong import kotlin.io.path.pathString import kotlin.system.exitProcess -suspend fun onMessage(data: SDLanTCP) { +suspend fun onMessage(scope: CoroutineScope, data: SDLanTCP) { val node = Node.getInstance() TerminalLogger.debugf {"message received"} @@ -70,10 +71,16 @@ suspend fun onMessage(data: SDLanTCP) { // println("got aes key: ${aeskey.toList()}, length is ${aeskey.size}") node.sendStunRequest() + scope.async { + node.probeNatType() + TerminalLogger.debugf { "nat type is ${node.nat_type}"} + } + /* CoroutineScope(Dispatchers.Default).async { node.probeNatType() TerminalLogger.debugf { "nat type is ${node.nat_type}"} } + */ } PacketType.RegisterSuperNAK -> { println("21") @@ -126,7 +133,7 @@ suspend fun onMessage(data: SDLanTCP) { } -suspend fun run_sdlan(iface: Iface, argument: Arguments, routeinfo: PunchnetServiceArgument?) { +suspend fun run_sdlan(scope: CoroutineScope, iface: Iface, argument: Arguments, routeinfo: PunchnetServiceArgument?) { UniqueNodeID.setBaseDir(argument.baseDir) val edgeUUID = UniqueNodeID.getUUID() val config = parseConfig(edgeUUID, argument) @@ -140,7 +147,7 @@ suspend fun run_sdlan(iface: Iface, argument: Arguments, routeinfo: PunchnetServ val toSocket = Channel(100) val start_stop_channel = Channel(100) - initEdge(iface, argument.token, config, toSocket, start_stop_channel) + initEdge(scope, iface, argument.token, config, toSocket, start_stop_channel) val tcp = argument.tcp.split(":") @@ -191,6 +198,27 @@ suspend fun run_sdlan(iface: Iface, argument: Arguments, routeinfo: PunchnetServ } */ + scope.launch { + while(true) { + val data = node.iface?.recv() + Log.d("SDLAN", "async receive data from iface: ${data?.size} bytes") + if (data == null) { + //delay(1000) + println("got data is null") + continue + } + if (data.isEmpty()) { + println("got data size 0") + // delay(1000) + continue + } + Log.d("SDLAN", "handle data form device starts") + node.iface?.handleDataFromDevice(node, data) + Log.d("SDLAN", "handle data form device stops") + } + + } + /* CoroutineScope((Dispatchers.IO)).async { while(true) { val data = node.iface?.recv() @@ -210,9 +238,12 @@ suspend fun run_sdlan(iface: Iface, argument: Arguments, routeinfo: PunchnetServ Log.d("SDLAN", "handle data form device stops") } } + */ - CoroutineScope(Dispatchers.IO).async { + // CoroutineScope(Dispatchers.IO).async { + scope.launch { initTCPConn( + scope, tcp[0], tcp[1].toInt(), start_stop_channel, AtomicLong(now), @@ -231,7 +262,7 @@ suspend fun run_sdlan(iface: Iface, argument: Arguments, routeinfo: PunchnetServ start_stop_channel.send(StartStopChanInfo(StartStopFlag.IsStart, null)) val cancel = Channel(100) - runEdgeLoop(node, cancel) + runEdgeLoop(scope, node, cancel) while(true) { TerminalLogger.debugf {"ping to sn"} @@ -240,24 +271,24 @@ suspend fun run_sdlan(iface: Iface, argument: Arguments, routeinfo: PunchnetServ } } -suspend fun runEdgeLoop(node: Node, cancel: ReceiveChannel) { +suspend fun runEdgeLoop(scope: CoroutineScope, node: Node, cancel: ReceiveChannel) { node.ping_to_sn() - CoroutineScope(Dispatchers.Default).async { - loopSocketV4(node, node.udpSockV4, cancel) + scope.launch { + loopSocketV4(scope, node, node.udpSockV4, cancel) } } -suspend fun loopSocketV4(node: Node, sock: SDLanSocket, cancel: ReceiveChannel) { - val job_stun_request = CoroutineScope(Dispatchers.Default).async { +suspend fun loopSocketV4(scope: CoroutineScope, node: Node, sock: SDLanSocket, cancel: ReceiveChannel) { + val job_stun_request = scope.async { while(true) { delay(10_000) node.sendStunRequest() } } - val job_handle_packet = CoroutineScope(Dispatchers.Default).async { + val job_handle_packet = scope.async { while(true) { - readAndParsePacket(node, sock) + readAndParsePacket(scope, node, sock) } } @@ -276,7 +307,7 @@ suspend fun loopSocketV4(node: Node, sock: SDLanSocket, cancel: ReceiveChannel { @@ -347,18 +378,18 @@ suspend fun handleAPacket(node: Node, from: SocketAddress, data: ByteBuffer) { } -fun initEdge(iface: Iface, token: String, config: NodeConfig, toSocket: SendChannel, startStopChannel: SendChannel) { +fun initEdge(scope: CoroutineScope, iface: Iface, token: String, config: NodeConfig, toSocket: SendChannel, startStopChannel: SendChannel) { val rsa = RSA.getRSA() val pathname = Paths.get(config.baseDir, RSAConfig.BASE_DIR).pathString Log.d("DIR", "pathname = $pathname") rsa.generateKeyPair(pathname) //rsa.generateKeyPair(Path.of(config.baseDir, RSAConfig.BASE_DIR).name) - val sockV4 = SDLanSocket("0.0.0.0", config.localPort) + val sockV4 = SDLanSocket(scope, "0.0.0.0", config.localPort) var sockMulticast: SDLanSocket? = null if (!config.dropMulticast) { - sockMulticast = SDLanSocket(SDLanMulticastConfig.MULTICAST_V4.toIPV4String(), SDLanMulticastConfig.MULTICAST_PORT) + sockMulticast = SDLanSocket(scope, SDLanMulticastConfig.MULTICAST_V4.toIPV4String(), SDLanMulticastConfig.MULTICAST_PORT) } Node.initialize( @@ -376,6 +407,7 @@ fun initEdge(iface: Iface, token: String, config: NodeConfig, toSocket: SendChan } suspend fun initTCPConn( + scope: CoroutineScope, tcpHost: String, tcpPort: Int, start_stop: Channel, @@ -383,7 +415,7 @@ suspend fun initTCPConn( connected: AtomicBoolean, toSocket: ReceiveChannel, onConnected: suspend (stream: Socket, pktID: Int?)->Unit, - onMessage: suspend (SDLanTCP)->Unit, + onMessage: suspend (CoroutineScope, SDLanTCP)->Unit, onDisconnected: suspend ()->Unit, connectingChan: SendChannel? ) { @@ -426,7 +458,8 @@ suspend fun initTCPConn( val outIP = ByteBuffer.wrap(socket.localAddress.address).getInt() node.outerIPV4.set(outIP) - val job_read_packet = CoroutineScope(Dispatchers.IO).async { + // val job_read_packet = CoroutineScope(Dispatchers.IO).async { + val job_read_packet = scope.async { val input = DataInputStream(socket.getInputStream()) try { println("job read packet starts") @@ -436,7 +469,7 @@ suspend fun initTCPConn( TerminalLogger.errorf {"tcp Packet is null"} break } - onMessage(tcpPacket) + onMessage(scope, tcpPacket) } } finally { TerminalLogger.errorf {"input closing"} @@ -444,7 +477,8 @@ suspend fun initTCPConn( } } - val job_write_to_packet = CoroutineScope(Dispatchers.IO).async { + // val job_write_to_packet = CoroutineScope(Dispatchers.IO).async { + val job_write_to_packet = scope.async { val output = DataOutputStream(socket.getOutputStream()) try { TerminalLogger.debugf {"job write to packet starts"} @@ -464,7 +498,8 @@ suspend fun initTCPConn( } } - val job_check_pong = CoroutineScope(Dispatchers.IO).async { + // val job_check_pong = CoroutineScope(Dispatchers.IO).async { + val job_check_pong = scope.async { println("job check pong starts") while(true) { delay(10_000) @@ -476,7 +511,8 @@ suspend fun initTCPConn( } } - val job_check_stop = CoroutineScope(Dispatchers.IO).async { + // val job_check_stop = CoroutineScope(Dispatchers.IO).async { + val job_check_stop = scope.async { println("job check stop starts") while(true) { try { diff --git a/app/src/main/java/com/jihe/punchnet/sdlan/network/socket.kt b/app/src/main/java/com/jihe/punchnet/sdlan/network/socket.kt index 0e5a189..913d708 100644 --- a/app/src/main/java/com/jihe/punchnet/sdlan/network/socket.kt +++ b/app/src/main/java/com/jihe/punchnet/sdlan/network/socket.kt @@ -14,7 +14,7 @@ import java.net.DatagramSocket import java.net.Inet4Address import java.net.SocketAddress -class SDLanSocket(val addr: String, val port: Int, val reuseAddress: Boolean = false) { +class SDLanSocket(val scope: CoroutineScope, val addr: String, val port: Int, val reuseAddress: Boolean = false) { private val connection: DatagramSocket = run { val sock = DatagramSocket(port, Inet4Address.getByName(addr)) if (reuseAddress) { @@ -27,7 +27,7 @@ class SDLanSocket(val addr: String, val port: Int, val reuseAddress: Boolean = f fun loop(): ReceiveChannel { val channel = Channel(100) - job = CoroutineScope(Dispatchers.Default).launch { + scope.launch { while (true) { val msg = receive() channel.send(msg)