mirror of https://github.com/bjdgyc/anylink.git
49 lines
990 B
Go
49 lines
990 B
Go
package handler
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"net/http"
|
|
"regexp"
|
|
)
|
|
|
|
var tcpParsers = []func([]byte) (uint8, string){
|
|
sniParser,
|
|
httpParser,
|
|
}
|
|
|
|
var (
|
|
sniRe = regexp.MustCompile("\x00\x00.{4}\x00.{2}([a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,6})\x00")
|
|
)
|
|
|
|
func onTCP(payload []byte) (uint8, string) {
|
|
ihl := (payload[12] & 0xf0) >> 2
|
|
data := payload[ihl:]
|
|
for _, parser := range tcpParsers {
|
|
if proto, info := parser(data); info != "" {
|
|
return proto, info
|
|
}
|
|
}
|
|
return acc_proto_tcp, ""
|
|
}
|
|
|
|
func sniParser(data []byte) (uint8, string) {
|
|
dataSize := len(data)
|
|
if dataSize < 2 || data[0] != 0x16 || data[1] != 0x03 {
|
|
return acc_proto_tcp, ""
|
|
}
|
|
m := sniRe.FindSubmatch(data)
|
|
if len(m) < 2 {
|
|
return acc_proto_tcp, ""
|
|
}
|
|
host := string(m[1])
|
|
return acc_proto_https, host
|
|
}
|
|
|
|
func httpParser(data []byte) (uint8, string) {
|
|
if req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(data))); err == nil {
|
|
return acc_proto_http, req.Host
|
|
}
|
|
return acc_proto_tcp, ""
|
|
}
|