123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package main
- import (
- "fmt"
- "io"
- "io/ioutil"
- mu "mfw/util"
- "net"
- "net/http"
- "os/exec"
- "strings"
- "time"
- )
- //检测端口是否可用
- func checkPort() (sPorts, fPorts []string) {
- output, err := exec.Command("netstat", "-tuln").Output()
- if err != nil {
- fmt.Println("执行netstat命令时出错:", err)
- return
- }
- lines := strings.Split(string(output), "\n")
- for _, port := range config.Ports {
- portOk := false
- for _, line := range lines {
- if line == "" {
- continue
- }
- fields := strings.Fields(line)
- if len(fields) >= 4 && strings.Contains(fields[3], fmt.Sprint(port)) { //端口存活
- portOk = true
- }
- }
- if portOk {
- sPorts = append(sPorts, fmt.Sprint(port))
- } else {
- fPorts = append(fPorts, fmt.Sprint(port))
- }
- }
- return
- }
- //测速
- func checkSpeed(addr string, updatename bool) (float64, float64) {
- conn, err := net.Dial("tcp", addr)
- if err != nil {
- return 0, 0
- }
- defer conn.Close()
- t1 := time.Now()
- buf := make([]byte, 1024)
- for i := 0; i < 50; i++ {
- io.ReadFull(conn, buf)
- }
- dd := time.Since(t1)
- t1 = time.Now()
- for i := 0; i < 50; i++ {
- conn.Write(buf)
- }
- for {
- _, err := conn.Write(buf)
- if err != nil {
- break
- }
- time.Sleep(10 * time.Millisecond)
- }
- ud := time.Since(t1)
- dp, up := float64(0.05)/dd.Seconds(), float64(0.05)/ud.Seconds()
- msg := fmt.Sprintf(MSG_TPL, config.VpsName, float64(0.05)/dd.Seconds(), float64(0.05)/ud.Seconds())
- fmt.Println("网速测试,", msg)
- if updatename {
- client.WriteObj("", "", mu.EVENT_UPDATE_MYNAME, mu.SENDTO_TYPE_P2P, []byte(msg))
- }
- return dp, up
- }
- //切换IP
- func changeIP() {
- sendMessageBeforChangeIp()
- defer sendMessageAfterChangeIp()
- for {
- fmt.Println("start change ip...")
- exec.Command("pppoe-stop").Run()
- exec.Command("pppoe-start").Run()
- fmt.Println("wait...")
- time.Sleep(10 * time.Second) //避免换IP后无法获取IP
- newIp := getMyIp() //获取新IP
- fmt.Println("newIp:", newIp)
- if newIp != "" && newIp != myoldip {
- fmt.Println("公网IP由", myoldip, "换为", newIp)
- ds, us := checkSpeed(config.CheckSpeedAddr, true) //测速
- if ds >= config.DownSpeedLimit && us >= config.UploadSpeedLimit { //网速达标
- fmt.Println("IP测速通过", newIp)
- myoldip = newIp
- break
- }
- }
- time.Sleep(5 * time.Second)
- }
- }
- func sendMessageBeforChangeIp() {
- fmt.Println("切换IP前发送消息...")
- bs := []byte{}
- for _, v := range cache {
- udpclient.WriteUdp([]byte{}, mu.OP_WILLCHANGEIP, v.Addr) //udp通知本服务器的下载器节点要切换ip,下掉所有服务
- bs = append(bs, []byte(v.Code)...)
- }
- client.WriteObj("", "", mu.SERVICE_DOWNLOAD_DELETE_NODE, mu.SENDTO_TYPE_ALL_RECIVER, bs)
- }
- func sendMessageAfterChangeIp() {
- fmt.Println("切换IP后发送消息...")
- cacheLock.Lock()
- for k, v := range cache { //告诉下载器重连
- udpclient.WriteUdp([]byte{}, mu.OP_NEWCLIENT, v.Addr)
- delete(cache, k)
- }
- cacheLock.Unlock()
- go func() {
- for i := 1; i <= 5; i++ {
- time.Sleep(5 * time.Second)
- if len(cache) > 0 {
- bs := []byte{}
- for k, v := range cache {
- fmt.Println("本机下载器机器码:", k, v.Code)
- bs = append(bs, []byte(v.Code)...)
- }
- client.WriteObj("", "", mu.SERVICE_DOWNLOAD_APPEND_NODE, mu.SENDTO_TYPE_ALL_RECIVER, bs)
- return
- }
- }
- }()
- }
- //获取IP
- func getMyIp() (ip string) {
- for i := 1; i <= 3; i++ {
- client := &http.Client{
- Timeout: 5 * time.Second, // 设置超时时间为5秒
- }
- resp, err := client.Get("https://api.ipify.org") // 使用ipify.org提供的IP查询API
- if err != nil {
- fmt.Println("获取公网IP失败:", err)
- continue
- }
- ipByte, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- fmt.Println("获取公网IP失败:", err)
- continue
- }
- resp.Body.Close()
- ip = string(ipByte)
- return
- }
- return
- }
- func checkIpAndPort() (sPorts, fPorts []string) {
- //检测IP
- if !changing { //正在切换IP,不做测速检测
- fmt.Println("测速...")
- ds, us := checkSpeed(config.CheckSpeedAddr, false) //测速
- if ds < config.DownSpeedLimit || us < config.UploadSpeedLimit { //网速不达标,切换IP
- go runChangeIP() //重新切换IP
- }
- }
- fmt.Println("检测端口...")
- //检测端口
- sPorts, fPorts = checkPort()
- if len(fPorts) == len(config.Ports) { //端口都不可用,重启端口
- go reStartPorts() //本轮检测重启,不可用
- }
- time.Sleep(1 * time.Second)
- return
- }
- //端口重启
- func reStartPorts() {
- tmpPort := []string{}
- for _, port := range config.Ports {
- tmpPort = append(tmpPort, ":"+fmt.Sprint(port))
- }
- exec.Command("/bin/sh", "-c", `kill -9 $(pidof "proxy")`).Run() //杀proxy
- exec.Command("proxy", "socks", "-t", "tcp", "-p", strings.Join(tmpPort, ","), "--forever", "--nolog", "--daemon").Run() //启动proxy
- }
|