1 Star 0 Fork 11

hjj194 / LingMaxDns

forked from LingMax / LingMaxDns 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
main.go 33.26 KB
一键复制 编辑 原始数据 按行查看 历史
LingMax 提交于 2022-07-09 11:18 . 增加说明
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472
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", //西南->重庆
"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])
}
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)
}
Go
1
https://gitee.com/hjj194/LingMaxDns.git
git@gitee.com:hjj194/LingMaxDns.git
hjj194
LingMaxDns
LingMaxDns
master

搜索帮助