install bug and new log api

This commit is contained in:
TenderIronh
2025-11-14 17:19:50 +08:00
parent d827fd108d
commit 6639f40d70
16 changed files with 575 additions and 302 deletions
+280 -112
View File
@@ -4,7 +4,6 @@ import android.app.*
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color import android.graphics.Color
import java.io.IOException
import android.net.VpnService import android.net.VpnService
import android.os.Binder import android.os.Binder
import android.os.Build import android.os.Build
@@ -22,6 +21,13 @@ import java.io.FileOutputStream
import java.nio.ByteBuffer import java.nio.ByteBuffer
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.json.JSONObject import org.json.JSONObject
import java.io.File
import java.net.InetAddress
import java.net.NetworkInterface
import kotlinx.coroutines.channels.Channel
import java.nio.channels.FileChannel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
data class Node(val name: String, val ip: String, val resource: String? = null) data class Node(val name: String, val ip: String, val resource: String? = null)
@@ -32,9 +38,10 @@ data class Network(
val gateway: String, val gateway: String,
val Nodes: List<Node> val Nodes: List<Node>
) )
class OpenP2PService : VpnService() { class OpenP2PService : VpnService() {
companion object { companion object {
private val LOG_TAG = OpenP2PService::class.simpleName private val LOG_TAG = "OpenP2PService"
} }
inner class LocalBinder : Binder() { inner class LocalBinder : Binder() {
@@ -44,12 +51,17 @@ class OpenP2PService : VpnService() {
private val binder = LocalBinder() private val binder = LocalBinder()
private lateinit var network: openp2p.P2PNetwork private lateinit var network: openp2p.P2PNetwork
private lateinit var mToken: String private lateinit var mToken: String
private var running:Boolean =true private var running: Boolean = true
private var sdwanRunning:Boolean =false private var sdwanRunning: Boolean = false
private var vpnInterface: ParcelFileDescriptor? = null private var vpnInterface: ParcelFileDescriptor? = null
private var sdwanJob: Job? = null private var sdwanJob: Job? = null
private val packetQueue = Channel<ByteBuffer>(capacity = 1024)
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onCreate() { override fun onCreate() {
Log.i(LOG_TAG, "onCreate - Thread ID = " + Thread.currentThread().id) val logDir = File(getExternalFilesDir(null), "log")
Logger.init(logDir)
Logger.i(LOG_TAG, "onCreate - Thread ID = " + Thread.currentThread().id)
var channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { var channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel("kim.hsl", "ForegroundService") createNotificationChannel("kim.hsl", "ForegroundService")
} else { } else {
@@ -64,7 +76,7 @@ class OpenP2PService : VpnService() {
val notification = channelId?.let { val notification = channelId?.let {
NotificationCompat.Builder(this, it) NotificationCompat.Builder(this, it)
// .setSmallIcon(R.mipmap.app_icon) // .setSmallIcon(R.mipmap.app_icon)
.setContentTitle("My Awesome App") .setContentTitle("My Awesome App")
.setContentText("Doing some work...") .setContentText("Doing some work...")
.setContentIntent(pendingIntent).build() .setContentIntent(pendingIntent).build()
@@ -76,7 +88,7 @@ class OpenP2PService : VpnService() {
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i( Logger.i(
LOG_TAG, LOG_TAG,
"onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().id "onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().id
) )
@@ -86,20 +98,20 @@ class OpenP2PService : VpnService() {
override fun onBind(p0: Intent?): IBinder? { override fun onBind(p0: Intent?): IBinder? {
val token = p0?.getStringExtra("token") val token = p0?.getStringExtra("token")
Log.i(LOG_TAG, "onBind token=$token") Logger.i(LOG_TAG, "onBind token=$token")
startOpenP2P(token) startOpenP2P(token)
return binder return binder
} }
private fun startOpenP2P(token : String?): Boolean { private fun startOpenP2P(token: String?): Boolean {
if (sdwanRunning) { if (sdwanRunning) {
return true return true
} }
Log.i(LOG_TAG, "startOpenP2P - Thread ID = " + Thread.currentThread().id + token) Logger.i(LOG_TAG, "startOpenP2P - Thread ID = " + Thread.currentThread().id + token)
val oldToken = Openp2p.getToken(getExternalFilesDir(null).toString()) val oldToken = Openp2p.getToken(getExternalFilesDir(null).toString())
Log.i(LOG_TAG, "startOpenP2P oldtoken=$oldToken newtoken=$token") Logger.i(LOG_TAG, "startOpenP2P oldtoken=$oldToken newtoken=$token")
if (oldToken=="0" && token==null){ if (oldToken == "0" && token == null) {
return false return false
} }
sdwanRunning = true sdwanRunning = true
@@ -112,7 +124,7 @@ class OpenP2PService : VpnService() {
1 1
) // /storage/emulated/0/Android/data/cn.openp2p/files/ ) // /storage/emulated/0/Android/data/cn.openp2p/files/
val isConnect = network.connect(30000) // ms val isConnect = network.connect(30000) // ms
Log.i(LOG_TAG, "login result: " + isConnect.toString()); Logger.i(LOG_TAG, "login result: " + isConnect.toString());
do { do {
Thread.sleep(1000) Thread.sleep(1000)
} while (network.connect(30000) && running) } while (network.connect(30000) && running)
@@ -123,152 +135,257 @@ class OpenP2PService : VpnService() {
private fun refreshSDWAN() { private fun refreshSDWAN() {
GlobalScope.launch { GlobalScope.launch {
Log.i(OpenP2PService.LOG_TAG, "refreshSDWAN start"); Logger.i(OpenP2PService.LOG_TAG, "refreshSDWAN start");
while (true) { while (true) {
Log.i(OpenP2PService.LOG_TAG, "waiting new sdwan config"); Logger.i(OpenP2PService.LOG_TAG, "waiting new sdwan config");
val buf = ByteArray(4096) val buf = ByteArray(32 * 1024)
val buffLen = Openp2p.getAndroidSDWANConfig(buf) val buffLen = Openp2p.getAndroidSDWANConfig(buf)
Log.i(OpenP2PService.LOG_TAG, "closing running sdwan instance"); Logger.i(OpenP2PService.LOG_TAG, "closing running sdwan instance");
sdwanRunning = false sdwanRunning = false
vpnInterface?.close() vpnInterface?.close()
vpnInterface = null vpnInterface = null
Thread.sleep(10000) sdwanJob?.join()
runSDWAN(buf.copyOfRange(0,buffLen.toInt() )) sdwanJob = serviceScope.launch(context = Dispatchers.IO) {
runSDWAN(buf.copyOfRange(0, buffLen.toInt()))
}
} }
Log.i(OpenP2PService.LOG_TAG, "refreshSDWAN end"); Logger.i(OpenP2PService.LOG_TAG, "refreshSDWAN end");
} }
} }
private suspend fun readTunLoop() { private suspend fun readTunLoop() {
val inputStream = FileInputStream(vpnInterface?.fileDescriptor).channel val inputStream = FileInputStream(vpnInterface?.fileDescriptor).channel
if (inputStream==null){ if (inputStream == null) {
Log.i(OpenP2PService.LOG_TAG, "open FileInputStream error: "); Logger.i(OpenP2PService.LOG_TAG, "open FileInputStream error: ");
return return
} }
Log.d(LOG_TAG, "read tun loop start") Logger.i(LOG_TAG, "read tun loop start")
val buffer = ByteBuffer.allocate(4096) val buffer = ByteBuffer.allocate(4096)
val byteArrayRead = ByteArray(4096) val byteArrayRead = ByteArray(4096)
while (sdwanRunning) { while (sdwanRunning) {
buffer.clear() buffer.clear()
val readBytes = inputStream.read(buffer) withContext(Dispatchers.IO) {
if (readBytes <= 0) { val readBytes = inputStream.read(buffer)
// Log.i(OpenP2PService.LOG_TAG, "inputStream.read error: ") if (readBytes > 0) {
delay(1) buffer.flip()
continue buffer.get(byteArrayRead, 0, readBytes)
// Logger.i(OpenP2PService.LOG_TAG, String.format("Openp2p.androidRead: %d", readBytes))
Openp2p.androidRead(byteArrayRead, readBytes.toLong())
// Logger.i(OpenP2PService.LOG_TAG, "inputStream.read error: ")
} else {
delay(50)
}
} }
buffer.flip()
buffer.get(byteArrayRead,0,readBytes)
Log.i(OpenP2PService.LOG_TAG, String.format("Openp2p.androidRead: %d", readBytes))
Openp2p.androidRead(byteArrayRead, readBytes.toLong())
} }
Log.d(LOG_TAG, "read tun loop end") Logger.i(LOG_TAG, "read tun loop end")
} }
private fun runSDWAN(buf:ByteArray) {
sdwanRunning=true
sdwanJob=GlobalScope.launch(context = Dispatchers.IO) {
Log.i(OpenP2PService.LOG_TAG, "runSDWAN start:${buf.decodeToString()}");
try{
var builder = Builder()
val jsonObject = JSONObject(buf.decodeToString())
val id = jsonObject.getLong("id")
val name = jsonObject.getString("name")
val gateway = jsonObject.getString("gateway")
val nodesArray = jsonObject.getJSONArray("Nodes")
val nodesList = mutableListOf<JSONObject>() private suspend fun runSDWAN(buf: ByteArray) {
for (i in 0 until nodesArray.length()) { // val localIps = listOf(
nodesList.add(nodesArray.getJSONObject(i)) // "fe80::14b6:a0ff:fe3e:64de" to 64,
} // "192.168.100.184" to 24,
// "10.93.158.91" to 32,
// "192.168.3.66" to 24
// )
//
// // 测试用例
// val testCases = listOf(
// "192.168.3.11" to true,
// "192.168.100.1" to true,
// "192.168.101.1" to false,
// "10.93.158.91" to true,
// "10.93.158.90" to false,
// "fe80::14b6:a0ff:fe3e:64de" to true,
// "fe80::14b6:a0ff:fe3e:64dd" to true // 在同一子网
// )
//
// for ((ip, expected) in testCases) {
// val result = isSameSubnet(ip, localIps)
// println("Testing IP: $ip, Expected: $expected, Result: $result")
// }
sdwanRunning = true
val myNodeName = Openp2p.getAndroidNodeName() Logger.i(OpenP2PService.LOG_TAG, "runSDWAN start:${buf.decodeToString()}");
Log.i(OpenP2PService.LOG_TAG, "getAndroidNodeName:${myNodeName}"); try {
val nodeList = nodesList.map { var builder = Builder()
val nodeName = it.getString("name") val jsonObject = JSONObject(buf.decodeToString())
val nodeIp = it.getString("ip") // debug sdwan info
if (nodeName==myNodeName){ // val jsonObject = JSONObject("""{"id":2817104318517097000,"name":"network1","gateway":"10.2.3.254/24","mode":"central","centralNode":"nanjin-192-168-0-82","enable":1,"tunnelNum":3,"mtu":1420,"Nodes":[{"name":"192-168-24-15","ip":"10.2.3.5"},{"name":"Alpine Linux-172.16","ip":"10.2.3.14","resource":"172.16.0.0/24"},{"name":"ctdeMacBook-Pro.local","ip":"10.2.3.22"},{"name":"dengjiandeMBP.sh.chaitin.net","ip":"10.2.3.32"},{"name":"DESKTOP-WIN11-ARM-self","ip":"10.2.3.19"},{"name":"eastdeMBP.sh.chaitin.net","ip":"10.2.3.3"},{"name":"FN-NAS-HP","ip":"10.2.3.1","resource":"192.168.100.0/24"},{"name":"huangruideMBP.sh.chaitin.net","ip":"10.2.3.30"},{"name":"iStoreOS-virtual-machine","ip":"10.2.3.12"},{"name":"k30s-redmi-10.2.33","ip":"10.2.3.27"},{"name":"lincheng-MacBook-Pro-3.sh.chaitin.net","ip":"10.2.3.15"},{"name":"localhost-mi-13","ip":"10.2.3.8"},{"name":"localhost-华为matepad11","ip":"10.2.3.13"},{"name":"luzhanwendeMacBook-Pro.local","ip":"10.2.3.17"},{"name":"Mi-pad2-local","ip":"10.2.3.9"},{"name":"nanjin-192-168-0-82","ip":"10.2.3.34"},{"name":"R7000P-2021","ip":"10.2.3.7"},{"name":"tanxiaolongsMBP.sh.chaitin.net","ip":"10.2.3.20"},{"name":"TUF-AX3000_V2-3804","ip":"10.2.3.25"},{"name":"WIN-CYZ-10.2.3.16","ip":"10.2.3.16"},{"name":"WODOUYAO","ip":"10.2.3.4"},{"name":"Zstrack01","ip":"10.2.3.51","resource":"192.168.24.0/22,192.168.20.0/24"},{"name":"小米14-localhost","ip":"10.2.3.23"}]}""")
val id = jsonObject.getLong("id")
val mtu = jsonObject.getInt("mtu")
val name = jsonObject.getString("name")
val gateway = jsonObject.getString("gateway")
val nodesArray = jsonObject.getJSONArray("Nodes")
val nodesList = mutableListOf<JSONObject>()
for (i in 0 until nodesArray.length()) {
nodesList.add(nodesArray.getJSONObject(i))
}
val myNodeName = Openp2p.getAndroidNodeName()
// 使用本地 IP 和子网判断是否需要添加路由
val localIps = getLocalIpAndSubnet()
Logger.i(OpenP2PService.LOG_TAG, "getAndroidNodeName:${myNodeName}");
val nodeList = nodesList.map {
val nodeName = it.getString("name")
val nodeIp = it.getString("ip")
if (nodeName == myNodeName) {
try {
Logger.i(LOG_TAG, "Attempting to add address: $nodeIp/24")
builder.addAddress(nodeIp, 24) builder.addAddress(nodeIp, 24)
Logger.i(LOG_TAG, "Successfully added address")
} catch (e: Exception) {
Logger.e(LOG_TAG, "Failed to add address $nodeIp: ${e.message}")
throw e // or handle gracefully
} }
val nodeResource = if (it.has("resource")) it.getString("resource") else null }
val parts = nodeResource?.split("/") val nodeResource = it.optString("resource", null)
if (parts?.size == 2) { if (!nodeResource.isNullOrEmpty()) {
val ipAddress = parts[0] // 可能是多个网段,用逗号分隔
val subnetMask = parts[1] val resourceList = nodeResource.split(",")
builder.addRoute(ipAddress, subnetMask.toInt()) for (resource in resourceList) {
Log.i(OpenP2PService.LOG_TAG, "sdwan addRoute:${ipAddress},${subnetMask.toInt()}"); val parts = resource.split("/")
if (parts.size == 2) {
val ipAddress = parts[0].trim()
val subnetMask = parts[1].trim()
// 判断是否属于本机网段
if (!isSameSubnet(ipAddress, localIps)) {
builder.addRoute(ipAddress, subnetMask.toInt())
Logger.i(
OpenP2PService.LOG_TAG,
"sdwan addRoute:${ipAddress},${subnetMask}"
)
} else {
Logger.i(
OpenP2PService.LOG_TAG,
"Skipped adding route for ${ipAddress}, already in local subnet"
)
}
} else {
Logger.w(OpenP2PService.LOG_TAG, "Invalid resource format: $resource")
}
} }
Node(nodeName, nodeIp, nodeResource)
} }
val network = Network(id, name, gateway, nodeList) Node(nodeName, nodeIp, nodeResource)
println(network)
Log.i(OpenP2PService.LOG_TAG, "onBind");
builder.addDnsServer("223.5.5.5")
builder.addDnsServer("2400:3200::1") // alicloud dns v6 & v4
builder.addRoute("10.2.3.0", 24)
// builder.addRoute("0.0.0.0", 0);
builder.setSession(LOG_TAG!!)
builder.setMtu(1420)
vpnInterface = builder.establish()
if (vpnInterface==null){
Log.e(OpenP2PService.LOG_TAG, "start vpnservice error: ");
}
val outputStream = FileOutputStream(vpnInterface?.fileDescriptor).channel
if (outputStream==null){
Log.e(OpenP2PService.LOG_TAG, "open FileOutputStream error: ");
return@launch
}
val byteArrayWrite = ByteArray(4096)
launch {
readTunLoop()
}
Log.d(LOG_TAG, "write tun loop start")
while (sdwanRunning) {
val len = Openp2p.androidWrite(byteArrayWrite)
Log.i(OpenP2PService.LOG_TAG, String.format("Openp2p.androidWrite: %d",len));
val writeBytes = outputStream?.write(ByteBuffer.wrap(byteArrayWrite))
if (writeBytes != null && writeBytes <= 0) {
Log.i(OpenP2PService.LOG_TAG, "outputStream?.write error: ");
continue
}
}
outputStream.close()
// 关闭 VPN 接口
vpnInterface?.close()
// 置空变量以释放资源
vpnInterface = null
Log.d(LOG_TAG, "write tun loop end")
}catch (e: Exception) {
// 捕获异常并记录
Log.e("VPN Connection", "发生异常: ${e.message}")
} }
Log.i(OpenP2PService.LOG_TAG, "runSDWAN end");
val network = Network(id, name, gateway, nodeList)
println(network)
Logger.i(OpenP2PService.LOG_TAG, "onBind");
builder.addDnsServer("119.29.29.29")
builder.addDnsServer("2400:3200::1") // alicloud dns v6 & v4
// builder.addRoute("10.2.3.0", 24)
// builder.addRoute("0.0.0.0", 0);
val gatewayStr = jsonObject.optString("gateway", "")
val subNet = getNetworkAddress(gatewayStr)
if (subNet != null) {
val (netIp, prefix) = subNet
builder.addRoute(netIp, prefix)
Logger.i(OpenP2PService.LOG_TAG, "Added route from gateway: $netIp/$prefix")
} else {
Logger.w(OpenP2PService.LOG_TAG, "Invalid gateway format: $gatewayStr")
}
builder.setSession(LOG_TAG!!)
builder.setMtu(mtu)
vpnInterface = builder.establish()
if (vpnInterface == null) {
Log.e(OpenP2PService.LOG_TAG, "start vpnservice error: ");
}
val byteArrayWrite = ByteArray(4096)
serviceScope.launch(Dispatchers.IO) {
readTunLoop() // 文件读操作,适合 Dispatchers.IO
}
val outputStream = FileOutputStream(vpnInterface?.fileDescriptor).channel
if (outputStream == null) {
Log.e(OpenP2PService.LOG_TAG, "open FileOutputStream error: ");
return
}
Logger.i(LOG_TAG, "write tun loop start")
while (sdwanRunning) {
val len = Openp2p.androidWrite(byteArrayWrite, 3000)
if (len > mtu || len.toInt() == 0) {
continue
}
try {
val writeBytes =
outputStream?.write(ByteBuffer.wrap(byteArrayWrite, 0, len.toInt()))
if (writeBytes != null && writeBytes <= 0) {
Logger.e(LOG_TAG, "outputStream.write failed: $writeBytes")
}
} catch (e: Exception) {
Logger.e(LOG_TAG, "outputStream.write exception: ${e.message}")
e.printStackTrace()
continue
}
}
outputStream.close()
vpnInterface?.close()
vpnInterface = null
Logger.i(LOG_TAG, "write tun loop end")
} catch (e: Exception) {
Logger.i("VPN Connection", "发生异常: ${e.message}")
} }
Logger.i(OpenP2PService.LOG_TAG, "runSDWAN end");
} }
/**
* 将 "10.2.3.254/16" 这样的 CIDR 转成正确对齐的网络地址,如 "10.2.0.0/16"
*/
fun getNetworkAddress(cidr: String): Pair<String, Int>? {
val parts = cidr.trim().split("/")
if (parts.size != 2) return null
val ip = parts[0]
val prefix = parts[1].toIntOrNull() ?: return null
if (prefix !in 0..32) return null
val octets = ip.split(".").map { it.toInt() }
if (octets.size != 4) return null
// 转成整数
val ipInt = (octets[0] shl 24) or (octets[1] shl 16) or (octets[2] shl 8) or octets[3]
// 生成掩码并计算网络地址
val mask = if (prefix == 0) 0 else (-1 shl (32 - prefix))
val networkInt = ipInt and mask
// 转回点分十进制
val networkIp = listOf(
(networkInt shr 24) and 0xFF,
(networkInt shr 16) and 0xFF,
(networkInt shr 8) and 0xFF,
networkInt and 0xFF
).joinToString(".")
return networkIp to prefix
}
override fun onDestroy() { override fun onDestroy() {
Log.i(LOG_TAG, "onDestroy - Thread ID = " + Thread.currentThread().id)
super.onDestroy() super.onDestroy()
Logger.i(LOG_TAG, "onDestroy - Canceling service scope")
serviceScope.cancel() // 取消所有与服务相关的协程
} }
override fun onUnbind(intent: Intent?): Boolean { override fun onUnbind(intent: Intent?): Boolean {
Log.i(LOG_TAG, "onUnbind - Thread ID = " + Thread.currentThread().id) Logger.i(LOG_TAG, "onUnbind - Thread ID = " + Thread.currentThread().id)
stopSelf() stopSelf()
return super.onUnbind(intent) return super.onUnbind(intent)
} }
fun isConnected(): Boolean { fun isConnected(): Boolean {
if (!::network.isInitialized) return false if (!::network.isInitialized) return false
return network.connect(1000) return network.connect(1000)
} }
fun stop() { fun stop() {
running=false running = false
stopSelf() stopSelf()
Openp2p.stop() Openp2p.stop()
} }
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String? { private fun createNotificationChannel(channelId: String, channelName: String): String? {
val chan = NotificationChannel( val chan = NotificationChannel(
@@ -282,3 +399,54 @@ class OpenP2PService : VpnService() {
return channelId return channelId
} }
} }
// 获取本机所有IP地址和对应的子网信息
fun getLocalIpAndSubnet(): List<Pair<String, Int>> {
val localIps = mutableListOf<Pair<String, Int>>()
val networkInterfaces = NetworkInterface.getNetworkInterfaces()
// 手动添加测试数据
//localIps.add(Pair("192.168.3.33", 24))
while (networkInterfaces.hasMoreElements()) {
val networkInterface = networkInterfaces.nextElement()
if (networkInterface.isUp && !networkInterface.isLoopback) {
val interfaceAddresses = networkInterface.interfaceAddresses
for (interfaceAddress in interfaceAddresses) {
val address = interfaceAddress.address
val prefixLength = interfaceAddress.networkPrefixLength
if (address is InetAddress) {
localIps.add(Pair(address.hostAddress, prefixLength.toInt()))
}
}
}
}
return localIps
}
// 判断某个IP是否与本机某网段匹配
fun isSameSubnet(ipAddress: String, localIps: List<Pair<String, Int>>): Boolean {
val targetIp = InetAddress.getByName(ipAddress).address
for ((localIp, prefixLength) in localIps) {
val localIpBytes = InetAddress.getByName(localIp).address
val mask = createSubnetMask(prefixLength, localIpBytes.size) // 动态生成掩码
// 比较目标 IP 和本地 IP 的网络部分
if (targetIp.indices.all { i ->
(targetIp[i].toInt() and mask[i].toInt()) == (localIpBytes[i].toInt() and mask[i].toInt())
}) {
return true
}
}
return false
}
// 根据前缀长度动态生成子网掩码
fun createSubnetMask(prefixLength: Int, addressLength: Int): ByteArray {
val mask = ByteArray(addressLength)
for (i in 0 until prefixLength / 8) {
mask[i] = 0xFF.toByte()
}
if (prefixLength % 8 != 0) {
mask[prefixLength / 8] = (0xFF shl (8 - (prefixLength % 8))).toByte()
}
return mask
}
+79 -33
View File
@@ -1,45 +1,91 @@
package cn.openp2p package cn.openp2p
import android.content.* import android.util.Log
import java.text.SimpleDateFormat
import java.io.BufferedWriter
import java.io.File import java.io.File
import java.io.FileWriter import java.io.FileWriter
import java.text.SimpleDateFormat
import java.util.*
import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.Color
import java.io.IOException import java.io.IOException
import android.net.VpnService import java.util.Date
import android.os.Binder import java.util.Locale
import android.os.Build
import android.os.IBinder
import android.os.ParcelFileDescriptor
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import cn.openp2p.ui.login.LoginActivity
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import openp2p.Openp2p
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.ByteBuffer
import kotlinx.coroutines.*
import org.json.JSONObject
object Logger { object Logger {
private val logFile: File = File("app.log") private const val LOG_TAG = "OpenP2PLogger"
private var logFile: File? = null
private var bufferedWriter: BufferedWriter? = null
fun log(message: String) { // 初始化日志文件
val timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date()) fun init(logDir: File, logFileName: String = "app.log") {
val logMessage = "$timestamp: $message\n" if (!logDir.exists()) logDir.mkdirs()
logFile = File(logDir, logFileName)
try { try {
val fileWriter = FileWriter(logFile, true) bufferedWriter = BufferedWriter(FileWriter(logFile, true))
fileWriter.append(logMessage) } catch (e: IOException) {
fileWriter.close() Log.e(LOG_TAG, "Failed to initialize BufferedWriter: ${e.message}")
} catch (e: Exception) {
e.printStackTrace()
} }
} }
// 写日志(线程安全)
@Synchronized
fun log(level: String, tag: String, message: String, throwable: Throwable? = null) {
val timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
val logMessage = "$timestamp $level $tag: $message"
// 打印到 console
when (level) {
"ERROR" -> Log.e(tag, message, throwable)
"WARN" -> Log.w(tag, message, throwable)
"INFO" -> Log.i(tag, message)
"DEBUG" -> Log.d(tag, message)
"VERBOSE" -> Log.v(tag, message)
}
// 写入文件
try {
bufferedWriter?.apply {
write(logMessage)
newLine()
flush()
}
throwable?.let {
bufferedWriter?.apply {
write(Log.getStackTraceString(it))
newLine()
flush()
}
}
} catch (e: IOException) {
Log.e(LOG_TAG, "Failed to write log to file: ${e.message}")
}
}
// 清理资源
fun close() {
try {
bufferedWriter?.close()
} catch (e: IOException) {
Log.e(LOG_TAG, "Failed to close BufferedWriter: ${e.message}")
}
}
// 简化方法
fun e(tag: String, message: String, throwable: Throwable? = null) {
log("ERROR", tag, message, throwable)
}
fun w(tag: String, message: String, throwable: Throwable? = null) {
log("WARN", tag, message, throwable)
}
fun i(tag: String, message: String) {
log("INFO", tag, message)
}
fun d(tag: String, message: String) {
log("DEBUG", tag, message)
}
fun v(tag: String, message: String) {
log("VERBOSE", tag, message)
}
} }
+2 -2
View File
@@ -1,9 +1,9 @@
package main package main
import ( import (
op "openp2p/core" op2p "openp2p/core"
) )
func main() { func main() {
op.Run() op2p.Run()
} }
+3
View File
@@ -30,4 +30,7 @@ var (
ErrBuildTunnelBusy = errors.New("build tunnel busy") ErrBuildTunnelBusy = errors.New("build tunnel busy")
ErrMemAppTunnelNotFound = errors.New("memapp tunnel not found") ErrMemAppTunnelNotFound = errors.New("memapp tunnel not found")
ErrRemoteServiceUnable = errors.New("remote service unable") ErrRemoteServiceUnable = errors.New("remote service unable")
ErrAppWithoutTunnel = errors.New("p2papp has no available tunnel")
ErrWriteWindowFull = errors.New("writeWindow full")
ErrHeaderDataLen = errors.New("header datalen error")
) )
+39 -39
View File
@@ -11,26 +11,14 @@ import (
) )
func install() { func install() {
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion) gLog.i("openp2p start. version: %s", OpenP2PVersion)
gLog.Println(LvINFO, "Contact: QQ group 16947733, Email [email protected]") gLog.i("Contact: QQ group 16947733, Email [email protected]")
gLog.Println(LvINFO, "install start") gLog.i("install start")
defer gLog.Println(LvINFO, "install end") defer gLog.i("install end")
// auto uninstall
err := os.MkdirAll(defaultInstallPath, 0775)
if err != nil {
gLog.Printf(LvERROR, "MkdirAll %s error:%s", defaultInstallPath, err)
return
}
err = os.Chdir(defaultInstallPath)
if err != nil {
gLog.Println(LvERROR, "Chdir error:", err)
return
}
uninstall()
// save config file
parseParams("install", "") parseParams("install", "")
// auto uninstall
uninstall(false)
gLog.i("install path: %s", defaultInstallPath)
targetPath := filepath.Join(defaultInstallPath, defaultBinName) targetPath := filepath.Join(defaultInstallPath, defaultBinName)
d := daemon{} d := daemon{}
// copy files // copy files
@@ -38,37 +26,42 @@ func install() {
binPath, _ := os.Executable() binPath, _ := os.Executable()
src, errFiles := os.Open(binPath) // can not use args[0], on Windows call openp2p is ok(=openp2p.exe) src, errFiles := os.Open(binPath) // can not use args[0], on Windows call openp2p is ok(=openp2p.exe)
if errFiles != nil { if errFiles != nil {
gLog.Printf(LvERROR, "os.Open %s error:%s", os.Args[0], errFiles) gLog.e("os.Open %s error:%s", os.Args[0], errFiles)
return return
} }
dst, errFiles := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0775) dst, errFiles := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0775)
if errFiles != nil { if errFiles != nil {
gLog.Printf(LvERROR, "os.OpenFile %s error:%s", targetPath, errFiles) time.Sleep(time.Second * 5) // maybe windows defender occupied the file, retry
return dst, errFiles = os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0775)
if errFiles != nil {
gLog.e("os.OpenFile %s error:%s", targetPath, errFiles)
return
}
} }
_, errFiles = io.Copy(dst, src) _, errFiles = io.Copy(dst, src)
if errFiles != nil { if errFiles != nil {
gLog.Printf(LvERROR, "io.Copy error:%s", errFiles) gLog.e("io.Copy error:%s", errFiles)
return return
} }
src.Close() src.Close()
dst.Close() dst.Close()
// install system service // install system service
err = d.Control("install", targetPath, []string{"-d"}) err := d.Control("install", targetPath, []string{"-d"})
if err == nil { if err == nil {
gLog.Println(LvINFO, "install system service ok.") gLog.i("install system service ok.")
} }
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
err = d.Control("start", targetPath, []string{"-d"}) err = d.Control("start", targetPath, []string{"-d"})
if err != nil { if err != nil {
gLog.Println(LvERROR, "start openp2p service error:", err) gLog.e("start openp2p service error:%s", err)
} else { } else {
gLog.Println(LvINFO, "start openp2p service ok.") gLog.i("start openp2p service ok.")
} }
gLog.Println(LvINFO, "Visit WebUI on https://console.openp2p.cn") gConf.save()
gLog.i("Visit WebUI on https://console.openp2p.cn")
} }
func installByFilename() { func installByFilename() {
@@ -78,7 +71,7 @@ func installByFilename() {
} }
serverHost := params[1] serverHost := params[1]
token := params[2] token := params[2]
gLog.Println(LvINFO, "install start") gLog.i("install start")
targetPath := os.Args[0] targetPath := os.Args[0]
args := []string{"install"} args := []string{"install"}
args = append(args, "-serverhost") args = append(args, "-serverhost")
@@ -93,31 +86,38 @@ func installByFilename() {
cmd.Env = env cmd.Env = env
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
gLog.Println(LvERROR, "install by filename, start process error:", err) gLog.e("install by filename, start process error:%s", err)
return return
} }
gLog.Println(LvINFO, "install end") gLog.i("install end")
gLog.Println(LvINFO, "Visit WebUI on https://console.openp2p.cn") gLog.i("Visit WebUI on https://console.openp2p.cn")
fmt.Println("Press the Any Key to exit") fmt.Println("Press the Any Key to exit")
fmt.Scanln() fmt.Scanln()
os.Exit(0) os.Exit(0)
} }
func uninstall() {
gLog.Println(LvINFO, "uninstall start") func uninstall(rmFiles bool) {
defer gLog.Println(LvINFO, "uninstall end") gLog.i("uninstall start")
defer gLog.i("uninstall end")
d := daemon{} d := daemon{}
err := d.Control("stop", "", nil) err := d.Control("stop", "", nil)
if err != nil { // service maybe not install if err != nil { // service maybe not install
return gLog.d("stop service error:%s", err)
} }
err = d.Control("uninstall", "", nil) err = d.Control("uninstall", "", nil)
if err != nil { if err != nil {
gLog.Println(LvERROR, "uninstall system service error:", err) gLog.d("uninstall system service error:%s", err)
} else { } else {
gLog.Println(LvINFO, "uninstall system service ok.") gLog.i("uninstall system service ok.")
} }
time.Sleep(time.Second * 3)
binPath := filepath.Join(defaultInstallPath, defaultBinName) binPath := filepath.Join(defaultInstallPath, defaultBinName)
os.Remove(binPath + "0") os.Remove(binPath + "0")
os.Remove(binPath) os.Remove(binPath)
// os.RemoveAll(defaultInstallPath) // reserve config.json if rmFiles {
if err := os.RemoveAll(defaultInstallPath); err != nil {
gLog.e("RemoveAll %s error:%s", defaultInstallPath, err)
}
}
} }
+107 -88
View File
@@ -3,38 +3,33 @@ package openp2p
import ( import (
"log" "log"
"os" "os"
"path/filepath"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"time" "time"
) )
type LogLevel int type LogLevel int32
var gLog *logger var gLog *logger
const ( const (
LvDev LogLevel = -1 LvDev LogLevel = -1
LvDEBUG LogLevel = iota LvDEBUG LogLevel = 0
LvINFO LvINFO LogLevel = 1
LvWARN LvWARN LogLevel = 2
LvERROR LvERROR LogLevel = 3
) )
var ( const logFileNames string = ".log"
logFileNames map[LogLevel]string
loglevel map[LogLevel]string
)
func init() {
logFileNames = make(map[LogLevel]string)
loglevel = make(map[LogLevel]string)
logFileNames[0] = ".log"
loglevel[LvDEBUG] = "DEBUG"
loglevel[LvINFO] = "INFO"
loglevel[LvWARN] = "WARN"
loglevel[LvERROR] = "ERROR"
loglevel[LvDev] = "Dev"
var loglevel = map[LogLevel]string{
LvDEBUG: "DEBUG",
LvINFO: "INFO",
LvWARN: "WARN",
LvERROR: "ERROR",
LvDev: "Dev",
} }
const ( const (
@@ -43,62 +38,54 @@ const (
) )
type logger struct { type logger struct {
loggers map[LogLevel]*log.Logger logger *log.Logger
files map[LogLevel]*os.File files *os.File
level LogLevel level atomic.Int32
logDir string logDir string
mtx *sync.Mutex mtx sync.Mutex
lineEnding string lineEnding string
pid int pid int
maxLogSize int64 maxLogSize atomic.Int64
mode int mode int
stdLogger *log.Logger stdLogger *log.Logger
checkFileRunning bool
} }
func NewLogger(path string, filePrefix string, level LogLevel, maxLogSize int64, mode int) *logger { func NewLogger(path string, filePrefix string, level LogLevel, maxLogSize int64, mode int) *logger {
loggers := make(map[LogLevel]*log.Logger) logdir := filepath.Join(path, "log")
logfiles := make(map[LogLevel]*os.File) if err := os.MkdirAll(logdir, 0755); err != nil && mode&LogFile != 0 {
var ( return nil
logdir string
)
if path == "" {
logdir = "log/"
} else {
logdir = path + "/log/"
} }
os.MkdirAll(logdir, 0777) logFilePath := filepath.Join(logdir, filePrefix+logFileNames)
for lv := range logFileNames { f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
logFilePath := logdir + filePrefix + logFileNames[lv] if err != nil && mode&LogFile != 0 {
f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) log.Fatal(err)
if err != nil {
log.Fatal(err)
}
os.Chmod(logFilePath, 0644)
logfiles[lv] = f
loggers[lv] = log.New(f, "", log.LstdFlags|log.Lmicroseconds)
} }
var le string stdLog := log.New(f, "", log.LstdFlags|log.Lmicroseconds)
le := "\n"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
le = "\r\n" le = "\r\n"
} else {
le = "\n"
} }
pLog := &logger{loggers, logfiles, level, logdir, &sync.Mutex{}, le, os.Getpid(), maxLogSize, mode, log.New(os.Stdout, "", 0)} pLog := &logger{logger: stdLog,
files: f,
logDir: logdir,
lineEnding: le,
pid: os.Getpid(),
mode: mode,
stdLogger: log.New(os.Stdout, "", 0)}
pLog.setMaxSize(maxLogSize)
pLog.setLevel(level)
pLog.stdLogger.SetFlags(log.LstdFlags | log.Lmicroseconds) pLog.stdLogger.SetFlags(log.LstdFlags | log.Lmicroseconds)
go pLog.checkFile() go pLog.checkFile()
return pLog return pLog
} }
func (l *logger) setLevel(level LogLevel) { func (l *logger) setLevel(level LogLevel) {
l.mtx.Lock() l.level.Store(int32(level))
defer l.mtx.Unlock()
l.level = level
} }
func (l *logger) setMaxSize(size int64) { func (l *logger) setMaxSize(size int64) {
l.mtx.Lock() l.maxLogSize.Store(size)
defer l.mtx.Unlock()
l.maxLogSize = size
} }
func (l *logger) setMode(mode int) { func (l *logger) setMode(mode int) {
@@ -107,49 +94,61 @@ func (l *logger) setMode(mode int) {
l.mode = mode l.mode = mode
} }
func (l *logger) close() {
l.checkFileRunning = false
l.files.Close()
}
func (l *logger) checkFile() { func (l *logger) checkFile() {
if l.maxLogSize <= 0 { if l.maxLogSize.Load() <= 0 {
return return
} }
l.checkFileRunning = true
ticker := time.NewTicker(time.Minute) ticker := time.NewTicker(time.Minute)
for { for l.checkFileRunning {
select { select {
case <-ticker.C: case <-ticker.C:
l.mtx.Lock() f, e := l.files.Stat()
for lv, logFile := range l.files { if e != nil {
f, e := logFile.Stat() continue
if e != nil {
continue
}
if f.Size() <= l.maxLogSize {
continue
}
logFile.Close()
fname := f.Name()
backupPath := l.logDir + fname + ".0"
os.Remove(backupPath)
os.Rename(l.logDir+fname, backupPath)
newFile, e := os.OpenFile(l.logDir+fname, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if e == nil {
l.loggers[lv].SetOutput(newFile)
l.files[lv] = newFile
}
} }
l.mtx.Unlock() if f.Size() <= l.maxLogSize.Load() {
continue
}
l.mtx.Lock()
l.files.Close()
fname := f.Name()
backupPath := filepath.Join(l.logDir, fname+".0")
err := os.Remove(backupPath)
if err != nil {
log.Println("remove openp2p.log0 error:", err)
}
if err = os.Rename(filepath.Join(l.logDir, fname), backupPath); err != nil {
log.Println("rename openp2p.log error:", err)
}
if newFile, e := os.OpenFile(filepath.Join(l.logDir, fname), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644); e == nil {
l.logger.SetOutput(newFile)
l.files = newFile
l.mtx.Unlock()
}
case <-time.After(time.Second * 1):
} }
} }
} }
func (l *logger) Printf(level LogLevel, format string, params ...interface{}) { func (l *logger) Printf(level LogLevel, format string, params ...interface{}) {
l.mtx.Lock() if level < LogLevel(l.level.Load()) {
defer l.mtx.Unlock()
if level < l.level {
return return
} }
l.mtx.Lock()
defer l.mtx.Unlock()
pidAndLevel := []interface{}{l.pid, loglevel[level]} pidAndLevel := []interface{}{l.pid, loglevel[level]}
params = append(pidAndLevel, params...) params = append(pidAndLevel, params...)
if l.mode&LogFile != 0 { if l.mode&LogFile != 0 {
l.loggers[0].Printf("%d %s "+format+l.lineEnding, params...) l.logger.Printf("%d %s "+format+l.lineEnding, params...)
} }
if l.mode&LogConsole != 0 { if l.mode&LogConsole != 0 {
l.stdLogger.Printf("%d %s "+format+l.lineEnding, params...) l.stdLogger.Printf("%d %s "+format+l.lineEnding, params...)
@@ -157,18 +156,38 @@ func (l *logger) Printf(level LogLevel, format string, params ...interface{}) {
} }
func (l *logger) Println(level LogLevel, params ...interface{}) { func (l *logger) Println(level LogLevel, params ...interface{}) {
l.mtx.Lock() if level < LogLevel(l.level.Load()) {
defer l.mtx.Unlock()
if level < l.level {
return return
} }
l.mtx.Lock()
defer l.mtx.Unlock()
pidAndLevel := []interface{}{l.pid, " ", loglevel[level], " "} pidAndLevel := []interface{}{l.pid, " ", loglevel[level], " "}
params = append(pidAndLevel, params...) params = append(pidAndLevel, params...)
params = append(params, l.lineEnding) params = append(params, l.lineEnding)
if l.mode&LogFile != 0 { if l.mode&LogFile != 0 {
l.loggers[0].Print(params...) l.logger.Print(params...)
} }
if l.mode&LogConsole != 0 { if l.mode&LogConsole != 0 {
l.stdLogger.Print(params...) l.stdLogger.Print(params...)
} }
} }
func (l *logger) d(format string, params ...interface{}) {
l.Printf(LvDEBUG, format, params...)
}
func (l *logger) i(format string, params ...interface{}) {
l.Printf(LvINFO, format, params...)
}
func (l *logger) w(format string, params ...interface{}) {
l.Printf(LvWARN, format, params...)
}
func (l *logger) e(format string, params ...interface{}) {
l.Printf(LvERROR, format, params...)
}
func (l *logger) dev(format string, params ...interface{}) {
l.Printf(LvDev, format, params...)
}
+1 -1
View File
@@ -25,7 +25,7 @@ func Run() {
install() install()
return return
case "uninstall": case "uninstall":
uninstall() uninstall(true)
return return
} }
} else { } else {
+3
View File
@@ -4,7 +4,10 @@ import (
"github.com/openp2p-cn/wireguard-go/tun" "github.com/openp2p-cn/wireguard-go/tun"
) )
const optunMTU = 1420
var AndroidSDWANConfig chan []byte var AndroidSDWANConfig chan []byte
var preAndroidSDWANConfig string
type optun struct { type optun struct {
tunName string tunName string
+20 -10
View File
@@ -5,12 +5,14 @@
package openp2p package openp2p
import ( import (
"net" "time"
) )
const ( const (
tunIfaceName = "optun" tunIfaceName = "optun"
PIHeaderSize = 0 PIHeaderSize = 0
ReadTunBuffSize = 2048
ReadTunBuffNum = 16
) )
var AndroidReadTun chan []byte // TODO: multi channel var AndroidReadTun chan []byte // TODO: multi channel
@@ -35,27 +37,35 @@ func (t *optun) Write(bufs [][]byte, offset int) (int, error) {
func AndroidRead(data []byte, len int) { func AndroidRead(data []byte, len int) {
head := PacketHeader{} head := PacketHeader{}
parseHeader(data, &head) parseHeader(data, &head)
gLog.Printf(LvDev, "AndroidRead tun dst ip=%s,len=%d", net.IP{byte(head.dst >> 24), byte(head.dst >> 16), byte(head.dst >> 8), byte(head.dst)}.String(), len) // gLog.dev("AndroidRead tun dst ip=%s,len=%d", net.IP{byte(head.dst >> 24), byte(head.dst >> 16), byte(head.dst >> 8), byte(head.dst)}.String(), len)
buf := make([]byte, len) buf := make([]byte, len)
copy(buf, data) copy(buf, data)
AndroidReadTun <- buf AndroidReadTun <- buf
} }
func AndroidWrite(buf []byte) int { func AndroidWrite(buf []byte, timeoutMs int) int {
p := <-AndroidWriteTun timeout := time.Duration(timeoutMs) * time.Millisecond
copy(buf, p) select {
return len(p) case p := <-AndroidWriteTun:
if len(p) > int(gConf.sdwan.Mtu) {
gLog.e("AndroidWrite packet too large %d", len(p))
}
copy(buf, p)
return len(p)
case <-time.After(timeout):
return 0
}
} }
func GetAndroidSDWANConfig(buf []byte) int { func GetAndroidSDWANConfig(buf []byte) int {
p := <-AndroidSDWANConfig p := <-AndroidSDWANConfig
copy(buf, p) copy(buf, p)
gLog.Printf(LvINFO, "AndroidSDWANConfig=%s", p) gLog.i("AndroidSDWANConfig=%s", p)
return len(p) return len(p)
} }
func GetAndroidNodeName() string { func GetAndroidNodeName() string {
gLog.Printf(LvINFO, "GetAndroidNodeName=%s", gConf.Network.Node) gLog.i("GetAndroidNodeName=%s", gConf.Network.Node)
return gConf.Network.Node return gConf.Network.Node
} }
+7 -3
View File
@@ -22,7 +22,7 @@ func UDPRead(conn *net.UDPConn, timeout time.Duration) (ra net.Addr, head *openP
if timeout > 0 { if timeout > 0 {
err = conn.SetReadDeadline(time.Now().Add(timeout)) err = conn.SetReadDeadline(time.Now().Add(timeout))
if err != nil { if err != nil {
gLog.Println(LvERROR, "SetReadDeadline error") gLog.e("SetReadDeadline error")
return nil, nil, nil, 0, err return nil, nil, nil, 0, err
} }
} }
@@ -35,9 +35,13 @@ func UDPRead(conn *net.UDPConn, timeout time.Duration) (ra net.Addr, head *openP
} }
head = &openP2PHeader{} head = &openP2PHeader{}
err = binary.Read(bytes.NewReader(buff[:openP2PHeaderSize]), binary.LittleEndian, head) err = binary.Read(bytes.NewReader(buff[:openP2PHeaderSize]), binary.LittleEndian, head)
if err != nil || head.DataLen > uint32(len(buff)-openP2PHeaderSize) { if err != nil {
gLog.Println(LvERROR, "parse p2pheader error:", err) gLog.e("parse p2pheader error:%s", err)
return nil, nil, nil, 0, err return nil, nil, nil, 0, err
} }
if head.DataLen > uint32(len(buff)-openP2PHeaderSize) {
gLog.e("parse p2pheader error:%d", ErrHeaderDataLen)
return nil, nil, nil, 0, ErrHeaderDataLen
}
return return
} }
+8 -2
View File
@@ -63,13 +63,15 @@ func Discover() (nat NAT, err error) {
return return
} }
var n int var n int
socket.SetDeadline(time.Now().Add(3 * time.Second))
_, _, err = socket.ReadFromUDP(answerBytes) _, _, err = socket.ReadFromUDP(answerBytes)
if err != nil { if err != nil {
gLog.Println(LvDEBUG, "UPNP discover error:", err) gLog.d("UPNP discover error:%s", err)
return return
} }
for { for {
socket.SetDeadline(time.Now().Add(3 * time.Second))
n, _, err = socket.ReadFromUDP(answerBytes) n, _, err = socket.ReadFromUDP(answerBytes)
if err != nil { if err != nil {
break break
@@ -266,7 +268,11 @@ func soapRequest(url, function, message, domain string) (r *http.Response, err e
// log.Stderr("soapRequest ", req) // log.Stderr("soapRequest ", req)
r, err = http.DefaultClient.Do(req) client := &http.Client{
Timeout: 3 * time.Second,
}
r, err = client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+5 -2
View File
@@ -5,9 +5,12 @@ import (
"syscall" "syscall"
) )
const ( var (
defaultInstallPath = "/usr/local/openp2p" defaultInstallPath = "/usr/local/openp2p"
defaultBinName = "openp2p" )
const (
defaultBinName = "openp2p"
) )
func getOsName() (osName string) { func getOsName() (osName string) {
+5 -2
View File
@@ -9,9 +9,12 @@ import (
"syscall" "syscall"
) )
const ( var (
defaultInstallPath = "/usr/local/openp2p" defaultInstallPath = "/usr/local/openp2p"
defaultBinName = "openp2p" )
const (
defaultBinName = "openp2p"
) )
func getOsName() (osName string) { func getOsName() (osName string) {
+5 -2
View File
@@ -10,9 +10,12 @@ import (
"syscall" "syscall"
) )
const ( var (
defaultInstallPath = "/usr/local/openp2p" defaultInstallPath = "/usr/local/openp2p"
defaultBinName = "openp2p" )
const (
defaultBinName = "openp2p"
) )
func getOsName() (osName string) { func getOsName() (osName string) {
+6 -3
View File
@@ -11,9 +11,12 @@ import (
"golang.org/x/sys/windows/registry" "golang.org/x/sys/windows/registry"
) )
const ( var (
defaultInstallPath = "C:\\Program Files\\OpenP2P" defaultInstallPath = "C:\\Program Files\\OpenP2P"
defaultBinName = "openp2p.exe" )
const (
defaultBinName = "openp2p.exe"
) )
func getOsName() (osName string) { func getOsName() (osName string) {
@@ -47,7 +50,7 @@ func setRLimit() error {
func setFirewall() { func setFirewall() {
fullPath, err := filepath.Abs(os.Args[0]) fullPath, err := filepath.Abs(os.Args[0])
if err != nil { if err != nil {
gLog.Println(LvERROR, "add firewall error:", err) gLog.e("add firewall error:%s", err)
return return
} }
isXP := false isXP := false
+5 -3
View File
@@ -4,13 +4,15 @@ go 1.20
require ( require (
github.com/emirpasic/gods v1.18.1 github.com/emirpasic/gods v1.18.1
github.com/gorilla/websocket v1.4.2 github.com/gorilla/websocket v1.5.3
github.com/openp2p-cn/go-reuseport v0.3.2 github.com/openp2p-cn/go-reuseport v0.3.2
github.com/openp2p-cn/service v1.0.0 github.com/openp2p-cn/service v1.0.0
github.com/openp2p-cn/totp v0.0.0-20230421034602-0f3320ffb25e github.com/openp2p-cn/totp v0.0.0-20230421034602-0f3320ffb25e
github.com/openp2p-cn/wireguard-go v0.0.20241020
github.com/quic-go/quic-go v0.34.0 github.com/quic-go/quic-go v0.34.0
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54 github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54
github.com/xtaci/kcp-go/v5 v5.5.17 github.com/xtaci/kcp-go/v5 v5.5.17
golang.org/x/net v0.30.0
golang.org/x/sys v0.26.0 golang.org/x/sys v0.26.0
golang.zx2c4.com/wireguard/windows v0.5.3 golang.zx2c4.com/wireguard/windows v0.5.3
) )
@@ -33,9 +35,9 @@ require (
golang.org/x/crypto v0.28.0 // indirect golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect
golang.org/x/mod v0.21.0 // indirect golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/tools v0.26.0 // indirect golang.org/x/tools v0.26.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
google.golang.org/protobuf v1.33.0 // indirect golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
gvisor.dev/gvisor v0.0.0-20241128011400-745828301c93 // indirect gvisor.dev/gvisor v0.0.0-20241128011400-745828301c93 // indirect
) )