加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.go 33.48 KB
一键复制 编辑 原始数据 按行查看 历史
LingMax 提交于 2022-07-17 15:20 . 处理长城宽带 TIM延迟高
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477
package main
import (
//"fmt"
"encoding/binary"
"io"
"io/ioutil"
"os/exec"
"sync"
//"httpsproxy/ip2region"
"log"
"net"
"os"
"runtime"
"sort"
"strconv"
"strings"
"time"
"golang.org/x/net/dns/dnsmessage"
)
//域名信息
type HostInfo struct {
isCN bool //是否中国域名
Host string //域名
ips map[string]*IpInfo //ip数组
time int64 //处理时间
dnsGETaddr []*DNSADDR //请求查询ip的列表
ms_jc int64 //测速计次
ms_ip string //抢到的加速
isTcp int64 //是否有tcp
isHead int64
}
//IP信息
type DNSADDR struct {
msg *dnsmessage.Message //FNS查询ID
addr *net.UDPAddr
}
type IpInfo2 struct {
CityId int64
Country string
Region string
Province string
City string
ISP string
}
//IP信息
type IpInfo struct {
ms int64 //响应时间
ip string //IP
isCN bool //是否中国IP
ms_jc int64 //测速计次
isNOW int64 //是否正在使用
isNOW1 int64 //是否正在使用
}
var errTime = int64(999999) //默认秒数
var logger = log.New(os.Stderr, "httpsproxy:", log.Llongfile|log.LstdFlags)
var fmt *log.Logger
var HostCache map[string]*HostInfo
//var IR *ip2region.Ip2Region
var serverDNS *net.UDPConn
var dns119 *net.UDPAddr
var dns119server *net.UDPConn
var xx8877 *net.UDPAddr
var mutexb = sync.Mutex{}
var isset = map[string]bool{} //是否已存在
//var allClient *http.Client
var serverDNSIP = []string{
"119.29.29.29", //保底
"124.202.220.146", //华北->北京
"202.96.69.38", //东北->辽宁
"124.133.43.90", //华东->山东青岛
"210.21.223.204", //华南->广东
"118.182.148.250", //西北->甘肃
"218.75.136.129", //华中->湖南
"113.204.69.42", //西南->重庆
"221.179.40.22", //广东汕头
"211.162.62.1", //广东广州
"124.117.230.210", //新疆
"202.14.67.4", //香港
"61.57.229.1", //台湾
"205.171.3.65", //美国
"203.2.193.67", //澳大利亚
"210.220.163.82", //韩国
"142.103.1.1", //加拿大
"211.121.135.130", //日本
"91.214.72.33", //意大利
"5.159.215.254", //英国
"185.32.20.62", //阿尔巴尼亚
"195.214.240.136", //法国
"80.64.32.2", //西班牙
"186.249.80.37", //巴西
"212.122.4.2", //俄罗斯
"82.96.64.2", //德国
"202.129.240.138", //印度
"183.91.16.70", //越南
"202.136.162.11", //新加坡
"193.67.79.39", //荷兰
"208.67.222.222", //保底
}
var packArr = map[string][]*net.UDPAddr{}
type dnsHttp struct {
tcp *net.Conn
isRun bool
}
var allidnsHttp = []*dnsHttp{}
type ICMP struct {
Type uint8
Code uint8
Checksum uint16
Identifier uint16
SequenceNum uint16
}
//DNS信息
type DnsInfo struct {
ip string //IP
conn net.Conn //测速计次
isSend bool //是否忙碌中
}
var DNSserver map[string]*DnsInfo
var dnsip_all = "119.29.29.29"
var all_port = int(8287)
func main() {
conn2, _ := net.ListenUDP("udp", &net.UDPAddr{})
dns119server = conn2
dnsss2, _ := net.ResolveUDPAddr("udp4", "192.168.1.201:8877")
xx8877 = dnsss2
/*
allClient = &http.Client{
Timeout: 2000 * time.Millisecond,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return errors.New("something bad happened") // 禁止重定向
},
Transport: &http.Transport{
MaxIdleConnsPerHost: 60,
DisableKeepAlives: false,
DisableCompression: false,
},
}
*/
runtime.GOMAXPROCS(1) //要啥自行车 单线程够了
Exedir, r2ee := os.Executable()
fmt = logger
logger.Println("启动..请稍候 -D 临时调试显示日志(半小时自动关闭) -P53 指定使用53端口(默认8287)", Exedir)
for _, v := range os.Args {
if v == "-D" {
Exedir = ""
}
if v == "-P53" {
all_port = int(53)
}
//i = i
}
if r2ee == nil && Exedir != "" {
var cmd *exec.Cmd
for {
logger.Println("-D 子进程启动中...", Exedir)
if all_port == 53 {
cmd = exec.Command(Exedir, "-D", "-P53")
} else {
cmd = exec.Command(Exedir, "-D")
}
cmd.Start()
cmd.Wait()
}
}
for {
connx, err3 := net.DialTimeout("tcp", "223.6.6.6:80", 10*time.Second) // 3s timeout
if err3 != nil {
fmt.Println("223.6.6.6:80连接失败", err3)
time.Sleep(1 * time.Second)
continue
}
connx.Close()
break
}
/*for {
time.Sleep(1 * time.Second)
}*/
/*
var icmp ICMP
icmp.Type = 8
icmp.Code = 0
icmp.Checksum = 0
icmp.Identifier = 0
icmp.SequenceNum = 0
var buffer bytes.Buffer
binary.Write(&buffer, binary.BigEndian, icmp)
icmp.Checksum = CheckSum(buffer.Bytes())
buffer.Reset()
binary.Write(&buffer, binary.BigEndian, icmp)
buf := buffer.Bytes()
fmt.Print(buf)
*/
argx := "route |grep default |awk '{print $2}'"
cmd := exec.Command("/bin/sh", "-c", argx)
outx, erraa := cmd.Output()
fmt.Println("自动识别dns结果", string(outx), erraa)
if erraa == nil {
lsip := string(outx)
//检查ip合法
if len(lsip) <= 15 && len(lsip) >= 7 && len(strings.Split(lsip, ".")) == 4 {
serverDNSIP[0] = strings.Replace(strings.Replace(lsip, "\n", "", -1), "\r", "", -1)
fmt.Println("自动识别dns结果", dnsip_all)
}
}
//dnsip_all = "192.168.102.1"
fmt.Println("使用dns", dnsip_all)
DNSserver = make(map[string]*DnsInfo)
for i := 0; i < len(serverDNSIP); i++ {
go addDns(serverDNSIP[i])
//conn.Close()
}
HostCache = make(map[string]*HostInfo)
/*
region, err := ip2region.New("ip2region.db")
if err != nil {
fmt.Println(err, "自动加载/home/GoAutoDns/ip2region.db")
region, err = ip2region.New("/home/GoAutoDns/ip2region.db")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
IR = region
*/
conn, err2 := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("0.0.0.0"), Port: all_port})
if err2 != nil {
fmt.Println("端口监听失败", all_port, err2)
os.Exit(1)
}
serverDNS = conn
logger.Println("启动完成")
dnsss, _ := net.ResolveUDPAddr("udp4", dnsip_all+":53")
//dnsss, _ := net.ResolveUDPAddr("udp4", "211.162.61.236:53") //长城专用
dns119 = dnsss
go dns119run()
go httpProxy(all_port)
go exitxx()
//defer serverDNS.Close()
for {
buf := make([]byte, 1024)
n, addr, errx := serverDNS.ReadFromUDP(buf)
if errx != nil || n < 3 {
continue
}
buf = buf[:n]
//fmt.Println(addr)
//dns119server.WriteToUDP(buf, addr)
go dnsmsg(buf, addr)
dns119server.WriteToUDP(buf, dns119)
}
}
func exitxx() {
path := "/tmp/LingMaxDns" + strconv.Itoa(int(timems()/1000/86400)) + ".cache"
bb, errx := ioutil.ReadFile(path)
ss := ""
if errx == nil {
ss = string(bb)
}
arr := strings.Split(ss, "\n")
for i := 0; i < len(arr); i++ {
if arr[i] == "" {
continue
}
arrx := strings.Split(arr[i], "@")
if len(arrx) != 2 {
continue
}
HostCache[arrx[1]] = &HostInfo{
isCN: false, //是否中国域名
Host: arrx[1], //域名
ips: make(map[string]*IpInfo), //ip数组
time: 0, //处理时间
dnsGETaddr: []*DNSADDR{}, //请求查询ip的列表
ms_jc: 0,
ms_ip: arrx[0],
isTcp: 0,
isHead: 0,
}
HostCache[arrx[1]].ips[arrx[0]] = &IpInfo{
ms: 100, //响应时间
ip: arrx[0], //IP
isCN: false, //是否中国IP
ms_jc: 0, //测速计次
isNOW: 0,
isNOW1: 0,
}
}
for i := 0; i < 1800; i++ {
time.Sleep(1 * 1000 * time.Millisecond)
if os.Getppid() == 1 {
os.Exit(2)
}
// strconv.Itoa(os.Getppid())
}
mutexb.Lock()
str := ""
for host := range HostCache {
if len(HostCache[host].ms_ip) > 0 {
str += HostCache[host].ms_ip + "@" + host + "\n"
}
}
ioutil.WriteFile(path, []byte(str), 0777) //写入文件(字节数组)
os.Exit(1)
}
func addDns(ip string) {
for {
_, ok := DNSserver[ip]
if !ok {
time.Sleep(1 * time.Second)
continue
}
buf := make([]byte, 1024)
len1, err := DNSserver[ip].conn.Read(buf)
if err != nil || len1 < 3 {
time.Sleep(1 * time.Second)
continue
}
buf = buf[:len1]
buf = buf[2:] // tcp包转UDP包
alldata(buf, true)
}
}
func dns119run() {
for {
buf2 := make([]byte, 1024)
n, _, errx := dns119server.ReadFromUDP(buf2)
if errx != nil || n < 3 {
continue
}
buf2 = buf2[:n]
alldata(buf2, false)
}
}
func alldata(buf []byte, bz bool) string {
var msg dnsmessage.Message
if err := msg.Unpack(buf); err != nil {
return ""
}
if len(msg.Questions) < 1 {
return ""
}
question := msg.Questions[0]
host := question.Name.String()
//host = host[:len(host)-1]
ipv4 := ""
ipv4x := ""
issetx := false
nrnr := ""
if bz {
nrnr = nrnr + " bz "
}
mutexb.Lock()
for i := 0; i < len(msg.Answers); i++ {
msg.Answers[i].Header.TTL = 5
if dnsmessage.TypeA == msg.Answers[i].Header.Type && len(ipv4) > 0 {
b := msg.Answers[i].Body.(*dnsmessage.AResource).A
ipv4 := strconv.Itoa(int(b[0])) + "." + strconv.Itoa(int(b[1])) + "." + strconv.Itoa(int(b[2])) + "." + strconv.Itoa(int(b[3]))
_, ok4 := HostCache[host]
if ok4 {
_, ok3 := HostCache[host].ips[ipv4]
if !ok3 {
issetx = true
nrnr = nrnr + " isset "
}
go checkAdress(host, ipv4, !bz)
}
}
}
mutexb.Unlock()
if issetx {
time.Sleep(60 * time.Millisecond)
}
mutexb.Lock()
ttts := errTime
for i := 0; i < len(msg.Answers); i++ {
if dnsmessage.TypeA == msg.Answers[i].Header.Type {
b := msg.Answers[i].Body.(*dnsmessage.AResource).A
ipv4 := strconv.Itoa(int(b[0])) + "." + strconv.Itoa(int(b[1])) + "." + strconv.Itoa(int(b[2])) + "." + strconv.Itoa(int(b[3]))
_, ok4 := HostCache[host]
if ok4 {
_, ok3 := HostCache[host].ips[ipv4]
if ok3 {
nrnr = nrnr + " " + ipv4 + "ms" + strconv.Itoa(int(HostCache[host].ips[ipv4].ms))
}
if !bz && ok3 && HostCache[host].ips[ipv4].ms > 60 && len(HostCache[host].ms_ip) > 0 && len(ipv4x) < 1 {
ipv4x = HostCache[host].ms_ip
//msg.Answers[i].Body.(*dnsmessage.AResource).A = ipToByte(HostCache[host].ms_ip)
} else {
if bz {
break
}
if ok3 && HostCache[host].ips[ipv4].ms > 0 && HostCache[host].ips[ipv4].ms < 60 && HostCache[host].ips[ipv4].ms < ttts && len(HostCache[host].ms_ip) > 0 {
ipv4x = ipv4
ttts = HostCache[host].ips[ipv4].ms
}
}
}
}
}
for i := 0; i < len(msg.Answers); i++ {
msg.Answers[i].Header.TTL = 5
if dnsmessage.TypeA == msg.Answers[i].Header.Type && len(ipv4x) > 0 {
msg.Answers[i].Body.(*dnsmessage.AResource).A = ipToByte(ipv4x)
}
}
mutexb.Unlock()
mkey := host + "_" + strconv.Itoa(int(msg.Header.ID))
if !bz {
//fmt.Println(mkey)
}
mutexb.Lock()
_, ok1 := packArr[mkey]
mutexb.Unlock()
if !ok1 || bz {
return ""
}
xx("最终得到" + host + " => ip" + ipv4x + "预备IP" + HostCache[host].ms_ip + nrnr)
mutexb.Lock()
buf3, _ := msg.Pack()
for i := 0; i < len(packArr[mkey]); i++ {
addr := packArr[mkey][i]
serverDNS.WriteToUDP(buf3, addr)
}
packArr[mkey] = []*net.UDPAddr{}
mutexb.Unlock()
return ipv4
}
func sendDns(host string, buf []byte) {
isall := false
mutexb.Lock()
if HostCache[host].time < timems()-1000*60*30 || timems()-1000*30 > HostCache[host].time && len(HostCache[host].ips) == 0 {
for i := 0; i < len(serverDNSIP); i++ {
go host2ip(host, serverDNSIP[i], buf)
go host2ipHttp(host, serverDNSIP[i])
}
go host2ipHttp(host, "113.96.18.253") //广州电信 特地加上 TIM故障
go host2ipHttp(host, "113.70.38.1") //佛山电信 特地加上 TIM故障
isall = true
}
mutexb.Unlock()
isret := timems()-1000*3 < HostCache[host].time
if isret && len(HostCache[host].ms_ip) > 0 {
goDNS(host, HostCache[host].ms_ip, HostCache[host].ms_jc, "缓存")
return
}
d1 := []*IpInfo{}
mutexb.Lock() //mutex.Unlock()
for vip := range HostCache[host].ips {
d1 = append(d1, HostCache[host].ips[vip])
}
mutexb.Unlock()
sort.Slice(d1, func(i, j int) bool {
return d1[i].ms < d1[j].ms
//return rand.Intn(1) == 1
})
HostCache[host].time = timems()
mmss := int64(40)
if len(HostCache[host].ms_ip) > 0 {
go checkAdress(host, HostCache[host].ms_ip, false)
time.Sleep(20 * time.Millisecond)
}
for i := 0; i < len(d1); i++ {
if HostCache[host].ms_ip == d1[i].ip {
continue
}
if i > 3 && !isall {
break
}
if i == 0 && d1[i].ms == errTime {
//goDNS(host, d1[i].ip, HostCache[host].ms_jc, "没有加速成功先顶着")
}
go checkAdress(host, d1[i].ip, false)
if i > 1 && isall {
time.Sleep(time.Duration(mmss) * time.Millisecond)
mmss = int64(float64(mmss) * float64(0.6))
}
if i > 3 && !isall && len(HostCache[host].dnsGETaddr) < 1 {
break
}
}
}
func host2ip(host string, ip string, buf []byte) {
_, ok := DNSserver[ip]
if !ok {
conn, err2 := net.DialTimeout("tcp", ip+":53", 2*time.Second)
if err2 != nil {
return
}
DNSserver[ip] = &DnsInfo{
ip: ip,
conn: conn,
isSend: false,
}
}
buf2 := make([]byte, 2)
binary.BigEndian.PutUint16(buf2, uint16(len(buf)))
buf = append(buf2, buf...)
//fmt.Println(buf, uint16(len(buf)))
//buf := make([]byte, 1024)
_, err := DNSserver[ip].conn.Write(buf)
if err != nil {
if DNSserver[ip].isSend {
return
}
DNSserver[ip].isSend = true
DNSserver[ip].conn.Close()
conn, err2 := net.DialTimeout("tcp", ip+":53", 2*time.Second)
DNSserver[ip].isSend = false
if err2 != nil {
return
}
DNSserver[ip].conn = conn
DNSserver[ip].conn.Write(buf)
}
}
func host2ipHttp(host string, ip string) {
if len(host) < 2 {
return
}
host1 := string(host[:len(host)-1])
ix := -1
for ixc := 0; ixc < len(allidnsHttp); ixc++ {
if !allidnsHttp[ixc].isRun {
ix = ixc
break
}
}
if ix == -1 {
conn1, err := net.DialTimeout("tcp", "223.6.6.6:80", 3*time.Second) // 3s timeout
if err != nil {
return
}
mutexb.Lock()
allidnsHttp = append(allidnsHttp, &dnsHttp{tcp: &conn1, isRun: false})
mutexb.Unlock()
ix = len(allidnsHttp) - 1
}
allidnsHttp[ix].isRun = true
conn := *allidnsHttp[ix].tcp
defer func() { allidnsHttp[ix].isRun = false }()
strx := "GET /resolve?name=" + host1 + "&type=A&short=1&edns_client_subnet=" + ip + " HTTP/1.1\r\nHost: 223.6.6.6\r\nConnection:keep-alive\r\nUser-Agent: Mozilla/5.0\r\nAccept: */*\r\nContent-Length: 0\r\n\r\n"
_, err := conn.Write([]byte(strx))
if err != nil {
conn2, err := net.DialTimeout("tcp", "223.6.6.6:80", 3*time.Second) // 3s timeout
if err != nil {
return
}
allidnsHttp[ix].tcp = &conn2
conn = *allidnsHttp[ix].tcp
conn.Write([]byte(strx))
}
conn.SetReadDeadline((time.Now().Add(time.Millisecond * 1500)))
body := make([]byte, 2048)
len1, err := conn.Read(body)
if err != nil || len1 < 3 {
return
}
body = body[:len1]
/*
resp, err := allClient.Get("http://223.6.6.6/resolve?name=" + host + "&type=A&short=1&edns_client_subnet=" + ip)
if err != nil {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil || len(body) < 3 {
return
}
ss := string(body)
*/
if err != nil || len(body) < 3 {
return
}
ss := string(body)
ret := strings.Split(ss, "\r\n\r\n")
if len(ret) < 2 {
return
}
ss = ret[1]
if len(ss) < 3 {
return
}
ss = ss[1 : len(ss)-1]
ss = strings.Replace(ss, "\"", "", -1)
ips := strings.Split(ss, ",")
for i := 0; i < len(ips); i++ {
go checkAdress(host, ips[i], false)
}
}
func CheckSum(data []byte) uint16 {
var (
sum uint32
length int = len(data)
index int
)
for length > 1 {
sum += uint32(data[index])<<8 + uint32(data[index+1])
index += 2
length -= 2
}
if length > 0 {
sum += uint32(data[index])
}
sum += (sum >> 16)
return uint16(^sum)
}
func dnsmsg(buf []byte, addr *net.UDPAddr) {
if dnsmsg2(buf, addr) {
return
}
return
conn, err2 := net.ListenUDP("udp", &net.UDPAddr{})
if err2 != nil {
fmt.Println(err2)
return
}
defer conn.Close()
conn.WriteToUDP(buf, dns119)
conn.SetReadDeadline((time.Now().Add(time.Second * 1)))
buf2 := make([]byte, 1024)
n, _, errx := conn.ReadFromUDP(buf2)
if errx != nil {
return
}
buf2 = buf2[:n]
serverDNS.WriteToUDP(buf2, addr)
//fmt.Println("没有加速成功 用默认DNS")
}
func dnsmsg2(buf []byte, addr *net.UDPAddr) bool {
//return false
var msg dnsmessage.Message
if err := msg.Unpack(buf); err != nil {
//fmt.Println("解包失败", err)
return false
}
if len(msg.Questions) < 1 {
//fmt.Println("查询数量异常", msg)
return false
}
question := msg.Questions[0]
host := question.Name.String()
//host = host[:len(host)-1]
mkey := host + "_" + strconv.Itoa(int(msg.Header.ID))
mutexb.Lock()
_, ok1 := packArr[mkey]
if !ok1 {
packArr[mkey] = []*net.UDPAddr{}
}
packArr[mkey] = append(packArr[mkey], addr)
mutexb.Unlock()
go delset(mkey)
if dnsmessage.TypePTR == question.Type {
return true
ip := strings.Replace(host, ".in-addr.arpa.", "", 1)
msg.Response = true
name, _ := dnsmessage.NewName(ip)
rt := dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: question.Name,
Class: dnsmessage.ClassINET,
TTL: 5,
},
Body: &dnsmessage.PTRResource{
PTR: name,
},
}
msg.Answers = []dnsmessage.Resource{rt}
buf3, _ := msg.Pack()
serverDNS.WriteToUDP(buf3, addr)
return true
}
/*
if dnsmessage.TypeA != question.Type {
fmt.Println("不是查询IP", host)
return false
}
if host == "m.baidu.com." {
fmt.Println("放行", host)
return false
}
*/
//fmt.Println(question, 111, msg)
mutexb.Lock()
_, ok := HostCache[host]
//fmt.Println(HostInfo1, ok)
if !ok {
HostCache[host] = &HostInfo{
isCN: false, //是否中国域名
Host: host, //域名
ips: make(map[string]*IpInfo), //ip数组
time: 0, //处理时间
dnsGETaddr: []*DNSADDR{}, //请求查询ip的列表
ms_jc: 0,
ms_ip: "",
isTcp: 0,
isHead: 0,
}
}
HostCache[host].dnsGETaddr = append(HostCache[host].dnsGETaddr, &DNSADDR{
msg: &msg,
addr: addr,
})
mutexb.Unlock()
if len(HostCache[host].dnsGETaddr) > 1 {
return true
}
xx("查询域名" + host)
ms_jc := HostCache[host].ms_jc
sendDns(host, buf)
return false
time.Sleep(1000 * time.Millisecond)
if ms_jc != HostCache[host].ms_jc {
return true
}
//fmt.Println("查询超时", host)
return false
}
func delset(mkey string) {
time.Sleep(4000 * time.Millisecond)
mutexb.Lock()
delete(packArr, mkey)
mutexb.Unlock()
}
func ipToByte(ip string) [4]byte {
a := [4]byte{0, 0, 0, 0}
ips := strings.Split(ip, ".")
if len(ips) != 4 {
return a
}
for i := 0; i < len(ips); i++ {
xi, _ := strconv.Atoi(ips[i])
a[i] = byte(xi)
}
return a
}
func NewAResource(host string, ip string) dnsmessage.Resource {
ips := strings.Split(ip, ".")
a := [4]byte{0, 0, 0, 0}
for i := 0; i < len(ips); i++ {
xi, _ := strconv.Atoi(ips[i])
a[i] = byte(xi)
}
query, _ := dnsmessage.NewName(host)
return dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: query,
Class: dnsmessage.ClassINET,
TTL: 5,
},
Body: &dnsmessage.AResource{
A: a,
},
}
}
//启动检查
func checkAdress(host string, ip string, isdns bool) bool {
if ip == "20.205.243.166" {
return false
}
_, errxy := net.ResolveIPAddr("ip", ip) // 解析域名得到 IP 地址结构
if errxy != nil {
return false
}
addr := getAddr(ip)
if addr.Country == "内网IP" {
return false
}
mutexb.Lock()
_, ok1 := HostCache[host].ips[ip]
mutexb.Unlock()
//fmt.Println(IpInfo1, ok)
if !ok1 {
//检查是否有同ip段的ip 如果有则过滤掉
ips := strings.Split(ip, ".")
if len(ips) != 4 {
return false
}
mutexb.Lock()
_, ok2 := isset[host+"_"+ips[0]+"."+ips[1]+"."+ips[2]+"."]
mutexb.Unlock()
if ok2 && !isdns {
return false
}
mutexb.Lock()
isset[host+"_"+ips[0]+"."+ips[1]+"."+ips[2]+"."] = true
//addr, _ := IR.BtreeSearch(ip)
//addr, _ := IR.MemorySearch(ip)
//isCN := addr.Country == "中国" || addr.City == "内网IP"
HostCache[host].ips[ip] = &IpInfo{
ms: 99999, //响应时间
ip: ip, //IP
isCN: false, //是否中国IP
ms_jc: 0, //测速计次
isNOW: 0,
isNOW1: 0,
}
mutexb.Unlock()
/*if isCN {
HostCache[host].isCN = isCN
}*/
//fmt.Println(host, ip)
} else {
if len(HostCache[host].dnsGETaddr) < 1 {
return false
}
mutexb.Lock()
if HostCache[host].ips[ip].isNOW > 0 || HostCache[host].ips[ip].isNOW1 > 0 {
mutexb.Unlock()
return false
}
mutexb.Unlock()
}
HostCache[host].isTcp = HostCache[host].ms_jc
go checkTcp(host, ip, HostCache[host].ms_jc)
go checkPing(host, ip, HostCache[host].ms_jc)
time.Sleep(10 * time.Millisecond)
go checkTcp(host, ip, HostCache[host].ms_jc)
go checkPing(host, ip, HostCache[host].ms_jc)
//ms_jc := HostCache[host].ms_jc
mutexb.Lock()
HostCache[host].ips[ip].isNOW1++
mutexb.Unlock()
time.Sleep(2000 * time.Millisecond)
mutexb.Lock()
HostCache[host].ips[ip].isNOW1--
mutexb.Unlock()
return true
}
//tcp测速
func checkTcp(host string, ip string, ms_jc int64) bool {
//time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
//fmt.Println("开始" + host + " => " + ip)
ts := timems()
mutexb.Lock()
if ms_jc < HostCache[host].ips[ip].ms_jc || len(HostCache[host].dnsGETaddr) < 1 {
mutexb.Unlock()
return false
}
HostCache[host].ips[ip].isNOW++
mutexb.Unlock()
conn, err := net.DialTimeout("tcp", ip+":80", 2*time.Second) // 3s timeout
mutexb.Lock()
HostCache[host].ips[ip].isNOW--
//fmt.Println("结束" + host + " => " + ip)
if err != nil {
if ms_jc == HostCache[host].ips[ip].ms_jc {
HostCache[host].ips[ip].ms = errTime
}
mutexb.Unlock()
return false
}
defer conn.Close()
if ms_jc < HostCache[host].ips[ip].ms_jc {
mutexb.Unlock()
return false
}
HostCache[host].ips[ip].ms = timems() - ts
mutexb.Unlock()
conn.Write([]byte("HEAD / HTTP/1.1\r\nHost: " + host + "\r\nUser-Agent: Mozilla/5.0\r\nAccept: */*\r\nContent-Length: 0\r\n\r\n"))
conn.SetReadDeadline((time.Now().Add(time.Millisecond * 2000)))
buf := make([]byte, 1024)
len1, err := conn.Read(buf)
mutexb.Lock()
if (err != nil || len1 < 4 || string(buf[:4]) != "HTTP") && HostCache[host].isHead > 0 && len(HostCache[host].ips) > 1 {
mutexb.Unlock()
return false
}
HostCache[host].isHead = HostCache[host].ms_jc + 1
HostCache[host].ips[ip].ms = timems() - ts
mutexb.Unlock()
goDNS(host, ip, ms_jc, "TCP加速成功")
return true
}
//ping测速
func checkPing(host string, ip string, ms_jc int64) bool {
// time.Sleep(10 * time.Millisecond)
//if HostCache[host].isTcp+1 >= HostCache[host].ms_jc && HostCache[host].isTcp != 0 {
// time.Sleep(200 * time.Millisecond)
//} else {
// time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
//}
mutexb.Lock()
if ms_jc < HostCache[host].ips[ip].ms_jc || len(HostCache[host].dnsGETaddr) < 1 {
mutexb.Unlock()
return false
}
mutexb.Unlock()
ts := timems()
laddr := net.IPAddr{IP: net.ParseIP("0.0.0.0")} // 得到本机的IP地址结构
raddr, errxy := net.ResolveIPAddr("ip", ip) // 解析域名得到 IP 地址结构
if errxy != nil {
return false
}
conn, err := net.DialIP("ip4:icmp", &laddr, raddr)
if err != nil {
return false
}
defer conn.Close()
recv := make([]byte, 1024)
buf := []byte{8, 0, 247, 255, 0, 0, 0, 0}
if _, err := conn.Write(buf); err != nil {
//fmt.Println(err.Error())
return false
}
conn.SetReadDeadline((time.Now().Add(time.Second * 2)))
mutexb.Lock()
HostCache[host].ips[ip].isNOW++
mutexb.Unlock()
_, err3 := conn.Read(recv)
mutexb.Lock()
HostCache[host].ips[ip].isNOW--
if err3 != nil {
if ms_jc == HostCache[host].ips[ip].ms_jc {
HostCache[host].ips[ip].ms = errTime
}
mutexb.Unlock()
return false
}
mutexb.Unlock()
time.Sleep(5 * time.Millisecond)
recv = make([]byte, 1024)
if _, err := conn.Write(buf); err != nil {
//fmt.Println(err.Error())
return false
}
conn.SetReadDeadline((time.Now().Add(time.Second * 2)))
mutexb.Lock()
HostCache[host].ips[ip].isNOW++
mutexb.Unlock()
_, err8 := conn.Read(recv)
mutexb.Lock()
HostCache[host].ips[ip].isNOW--
if err8 != nil {
if ms_jc == HostCache[host].ips[ip].ms_jc {
HostCache[host].ips[ip].ms = errTime
}
mutexb.Unlock()
return false
}
mutexb.Unlock()
time.Sleep(5 * time.Millisecond)
recv = make([]byte, 1024)
if _, err := conn.Write(buf); err != nil {
//fmt.Println(err.Error())
return false
}
conn.SetReadDeadline((time.Now().Add(time.Second * 2)))
mutexb.Lock()
HostCache[host].ips[ip].isNOW++
mutexb.Unlock()
_, err4 := conn.Read(recv)
mutexb.Lock()
HostCache[host].ips[ip].isNOW--
if err4 != nil {
if ms_jc == HostCache[host].ips[ip].ms_jc {
HostCache[host].ips[ip].ms = errTime
}
mutexb.Unlock()
return false
}
/*if len1 != len(buf) {
fmt.Println("长度异常", len1)
return false
}*/
if ms_jc < HostCache[host].ips[ip].ms_jc {
mutexb.Unlock()
return false
}
HostCache[host].ips[ip].ms = timems() - ts
mutexb.Unlock()
goDNS(host, ip, ms_jc, "ping加速成功")
return true
}
func goDNS(host string, ip string, ms_jc int64, from string) {
mutexb.Lock()
HostCache[host].ips[ip].ms_jc = HostCache[host].ms_jc
if ms_jc != HostCache[host].ms_jc && !(from == "TCP加速成功" && ms_jc > HostCache[host].isTcp) {
mutexb.Unlock()
return
}
/*
hostby, _ := dnsmessage.NewName(host)
ips := strings.Split(ip, ".")
a := [4]byte{0, 0, 0, 0}
for i := 0; i < len(ips); i++ {
xi, _ := strconv.Atoi(ips[i])
a[i] = byte(xi)
}
msg := dnsmessage.Message{
Header: dnsmessage.Header{Response: true, Authoritative: true},
Questions: []dnsmessage.Question{
{
Name: hostby,
Type: dnsmessage.TypeA,
Class: dnsmessage.ClassINET,
},
},
Answers: []dnsmessage.Resource{
{
Header: dnsmessage.ResourceHeader{
Name: hostby,
Type: dnsmessage.TypeA,
Class: dnsmessage.ClassINET,
TTL: 5,
},
Body: &dnsmessage.AResource{A: a},
},
},
}
*/
HostCache[host].ms_jc++
/*
for i := 0; i < len(HostCache[host].dnsGETaddr); i++ {
msg := HostCache[host].dnsGETaddr[i].msg
msg.Response = true
msg.Answers = []dnsmessage.Resource{NewAResource(host, ip)}
buf, _ := msg.Pack()
serverDNS.WriteToUDP(buf, HostCache[host].dnsGETaddr[i].addr)
}
*/
HostCache[host].dnsGETaddr = []*DNSADDR{}
HostCache[host].ips[ip].ms_jc = HostCache[host].ms_jc
if len(ip) > 0 && string(ip[len(ip)-1:]) != "." {
HostCache[host].ms_ip = ip
}
if from == "TCP加速成功" {
HostCache[host].isTcp = HostCache[host].ms_jc
}
xx("解析成功" + from + host + " => ip" + ip + " 延迟" + strconv.Itoa(int(HostCache[host].ips[ip].ms)))
//fmt.Println(from, "查询成功", HostCache[host].ips[ip].ms, "域名", host, "=>", ip)
mutexb.Unlock()
}
//获取毫秒
func timems() int64 {
return time.Now().UnixNano() / 1e6
}
func getAddr(ip string) IpInfo2 {
s3 := string(ip[0:3])
Country1 := ""
City1 := ""
if string(ip[0:1]) == "0" || s3 == "127" || s3 == "10." {
City1 = "内网IP"
Country1 = "内网IP"
} else {
s7 := string(ip[0:7])
if s7 == "192.168" || s7 == "172.16." || s7 == "172.17." || s7 == "172.18." || s7 == "172.19." || s7 == "172.20." || s7 == "172.21." || s7 == "172.22." || s7 == "172.23." || s7 == "172.24." || s7 == "172.25." || s7 == "172.26." || s7 == "172.27." || s7 == "172.28." || s7 == "172.29." || s7 == "172.30." || s7 == "172.31." {
City1 = "内网IP"
Country1 = "内网IP"
}
}
return IpInfo2{Country: Country1, City: City1}
}
//输出信息
func xx(str string) {
dns119server.WriteToUDP([]byte(str), xx8877)
}
//https代理
func httpProxy(port int) {
server, err := net.Listen("tcp", "0.0.0.0:"+strconv.Itoa(all_port))
if err != nil {
logger.Println("https代理其他失败")
return
}
defer server.Close()
for {
Conn, err := server.Accept()
if err != nil {
return
}
go tcp_handle(&Conn)
}
}
func tcp_handle(Conn *net.Conn) {
buf := make([]byte, 4096)
len1, err := (*Conn).Read(buf)
if err != nil || len1 < 10 {
return
}
str := string(buf[:len1])
wz_head := strings.Index(str, "\r\nHost: ")
if wz_head < 0 {
return
}
wz_head = wz_head + 8
wz_end := strings.Index(str[wz_head:], "\r\n")
if wz_end < 0 {
return
}
wz_end = wz_end + wz_head
hostPort := str[wz_head:wz_end]
listArr := strings.Split(hostPort, ":")
host := ""
port := ""
if len(listArr) == 2 {
host = listArr[0]
port = listArr[1]
} else if len(listArr) == 1 {
host = listArr[0]
port = "0"
} else {
return
}
head_len := strings.Index(str, "\r\n\r\n")
if wz_end > head_len || head_len == -1 {
return
}
ver := "HTTP/1.0"
head_len = head_len + 4
ls := strings.Index(str, " HTTP/")
if ls > head_len || ls == -1 {
return
}
/*
ver = str[ls+1 : strings.Index(str[ls:], "\r\n")]
ls = strings.Index(str, "\r\nContent-Length: ")
if ls > -1 {
ls = ls + 18
var ls_end = strings.Index(str[ls:], "\r\n")
dataLen, errl := strconv.Atoi(str[ls:ls_end])
if errl != nil {
fmt.Println(err)
return
}
if dataLen-(len(str)-head_len) > 0 {
send_len = ls - (len(str) - head_len) //后面这些字节直接放弃搜索
}
}
*/
//fmt.Println(11111, str)
sendData := [][]byte{}
if buf[0] == 67 && buf[1] == 79 {
if port == "0" {
port = "443"
}
(*Conn).Write([]byte(ver + " 200 OK\r\nConnection: close\r\nProxy-Connection: close\r\nProxy-agent: LingMax-proxy\r\nProxy-Content-Length: 0\r\nContent-Length: 0\r\n\r\n"))
} else {
if port == "0" {
port = "80"
}
lswz := strings.Index(str, " ") + 1
buf1 := buf[0:lswz]
buf2 := buf[lswz+7+len(hostPort):]
allbuf := []byte("")
for {
allbuf = append(buf1, buf2...)
str = string(allbuf)
wz_head = strings.Index(str, "\r\nProxy-")
if wz_head < 0 {
break
}
buf1 = allbuf[0:wz_head]
wz_end = strings.Index(string(allbuf[wz_head+2:]), "\r\n")
if wz_end < 0 {
break
}
buf2 = allbuf[wz_head+wz_end:]
}
//fmt.Println(hostPort)
//fmt.Println(string(buf2))
sendData = append(sendData, allbuf)
}
//fmt.Println(222222, str)
hostPort = host + ":" + port
host = host + "."
mutexb.Lock()
_, ok := HostCache[host]
mutexb.Unlock()
if !ok {
sendDnsBuf(host)
mutexb.Lock()
_, ok := HostCache[host]
mutexb.Unlock()
if !ok {
(*Conn).Close()
return
}
}
/*
for {
(*Conn).SetReadDeadline((time.Now().Add(100 * time.Millisecond)))
bufx := make([]byte, 4096)
len1x, errxa := (*Conn).Read(bufx)
if errxa != nil || len1x < 1 {
break
} else {
sendData = append(sendData, bufx[:len1x])
}
}
*/
addx := ""
d1 := []*IpInfo{}
mutexb.Lock() //mutex.Unlock()
for vip := range HostCache[host].ips {
d1 = append(d1, HostCache[host].ips[vip])
}
mutexb.Unlock()
sort.Slice(d1, func(i, j int) bool {
return d1[i].ms < d1[j].ms
//return rand.Intn(1) == 1
})
jc := 0
if ok && len(HostCache[host].ms_ip) > 0 {
hostPort = HostCache[host].ms_ip + ":" + port
go httpSend(Conn, hostPort, sendData, &addx, HostCache[host].ms_ip)
} else {
go httpSend(Conn, hostPort, sendData, &addx, host)
}
jc++
time.Sleep(2 * time.Second)
for i1 := 0; i1 < 5; i1++ {
for i := 0; i < len(d1); i++ {
if len(addx) > 0 {
if addx != host && string(addx[len(addx)-1:]) != "." {
HostCache[host].ms_ip = addx
}
return
}
if jc >= 5 {
continue
}
hostPort = d1[i].ip + ":" + port
go httpSend(Conn, hostPort, sendData, &addx, d1[i].ip)
time.Sleep(2 * time.Second)
jc++
}
}
defer (*Conn).Close()
defer func() {
(*Conn).Write([]byte("HTTP/1.0 500 Connection err \r\nContent-Length: 0\r\nProxy-agent: LingMax-proxy\r\n\r\n"))
}()
}
func sendDnsBuf(host string) {
msg := dnsmessage.Message{}
msg.Header.RecursionDesired = true
name, _ := dnsmessage.NewName(host)
rt := dnsmessage.Question{
Name: name,
Type: dnsmessage.TypeA,
Class: dnsmessage.ClassINET,
}
msg.Questions = []dnsmessage.Question{rt}
buf, err := msg.Pack()
if err != nil {
return
}
dnsmsg(buf, xx8877)
}
func httpSend(Conn *net.Conn, hostPort string, sendData [][]byte, addx *string, ip string) {
if len(*addx) > 0 {
return
}
remote_tcp, err := net.DialTimeout("tcp", hostPort, 10*time.Second) // 3s timeout
if err != nil {
//remote_tcp, err = net.DialTimeout("tcp", host+":"+port, 2*time.Second) // 3s timeout
fmt.Println(err)
return
}
defer remote_tcp.Close()
if len(sendData) > 0 {
//fmt.Println(string(sendData))
for i := 0; i < len(sendData); i++ {
remote_tcp.Write(sendData[i])
}
//go io.Copy(Conn, remote_tcp)
//io.Copy(remote_tcp, Conn)
/*
recv_len := 0
recv_add := 0
recv_ssss := -1
for {
bufx := make([]byte, 2048)
len1x, errx := Conn.Read(bufx)
if errx != nil {
return
}
bufx = bufx[:len1x]
remote_tcp.Write(bufx)
if recv_ssss == -1 {
recv_ssss = 0
str_recv := string(bufx)
sssLen := strings.Index(str_recv, "\r\nContent-Length: ")
if sssLen < 0 {
return
}
sssLen = sssLen + 18
eeeLen := strings.Index(string(str_recv[sssLen:]), "\r\n")
if eeeLen < 0 {
return
}
ecx, rerr := strconv.Atoi(str_recv[sssLen:eeeLen])
if rerr != nil || ecx < 1 {
return
}
recv_len = ecx
sssLen = strings.Index(str_recv, "\r\n\r\n")
if sssLen < 0 {
return
}
sssLen = sssLen + 4
bufx = bufx[sssLen:]
}
recv_add = recv_add + len(bufx)
if recv_len <= recv_add {
return
}
}
*/
} else {
//go io.Copy(Conn, remote_tcp)
//io.Copy(remote_tcp, Conn)
}
//recv := make([]byte, 1)
//remote_tcp.Read(recv)
if len(*addx) > 0 {
return
}
mutexb.Lock() //mutex.Unlock()
(*addx) = ip
mutexb.Unlock() //mutex.Unlock()
defer (*Conn).Close()
/*
defer func() {
(*Conn).Write([]byte("HTTP/1.0 500 Connection err \r\nContent-Length: 0\r\nProxy-agent: LingMax-proxy\r\n\r\n"))
}()
*/
//(*Conn).Write(recv)
go io.Copy(remote_tcp, (*Conn))
io.Copy((*Conn), remote_tcp)
//fmt.Println("开始 " + hostPort)
//fmt.Println("结束 " + hostPort)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化