Skip to content

Commit

Permalink
add pac auto config and auto download functions
Browse files Browse the repository at this point in the history
  • Loading branch information
asche910 committed Oct 18, 2019
1 parent f2ba858 commit 6911471
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 29 deletions.
9 changes: 3 additions & 6 deletions fly/cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var (
IV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
)

var cipherMap = map[string]*cipherEntity{
var CipherMap = map[string]*cipherEntity{
"aes-128-cfb": {16, 16, newAESCFBStream},
"aes-192-cfb": {24, 16, newAESCFBStream},
"aes-256-cfb": {32, 16, newAESCFBStream},
Expand Down Expand Up @@ -74,12 +74,9 @@ func NewCipherInstance(secretKey, method string) *Cipher {
if secretKey == "" {
secretKey = key
}
entity := cipherMap[method]
entity := CipherMap[method]
if entity == nil {
entity = cipherMap["aes-256-cfb"]
logger.Println("encrypt method: aes-256-cfb")
}else {
logger.Println("encrypt method:", method)
entity = CipherMap["aes-256-cfb"]
}

key := genKey(secretKey, entity.keyLen)
Expand Down
66 changes: 51 additions & 15 deletions fly/pac.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,60 @@ import (
"os"
)

func StartPAC() {
http.HandleFunc("/flynet.pac", func (w http.ResponseWriter, r *http.Request){
// the pac file should be placed at the same dir with current running file.
// but it is placed at the parent dir when development
file, err := os.Open(`flynet.pac`)
// return the stream and size of pac file
func GetPAC() ([]byte, int) {
// run from the same dir with flynet.pac
file, err := os.Open(`flynet.pac`)
if err != nil {
// run from cmd/client/client.go
file, err = os.Open("../../flynet.pac")
if err != nil {
// run from fly/pac_test.go
file, err = os.Open("../flynet.pac")
if err != nil {
logger.Println("pac file not found! start downlaod from github...")
err := downloadPAC()
logger.Println("pac file download completed!")
if err != nil {
return nil, 0
}
return GetPAC()
}
}
}

index := 0
fileBuff := make([]byte, 200*1024)
for {
logger.Println("start reading...")
n, err := file.Read(fileBuff[index:])
if err != nil {
fmt.Println(err)
// run from cmd/client/
file, _ = os.Open("../flynet.pac")
//file, _ = os.Open("../../flynet.pac")
if err == io.EOF {
logger.Println("read pac file ok.")
break
}
logger.Println("read pac file error --->", err)
}
w.Header().Set("Content-Type", "application/x-ns-proxy-autoconfig")
io.Copy(w, file)
w.WriteHeader(200)
index += n
}
return fileBuff, index
}

func downloadPAC() error {
fileName := "flynet.pac"
resp, err := http.Get("https://raw.githubusercontent.com/petronny/gfwlist2pac/master/gfwlist.pac")
if err != nil {
logger.Println("download pac file failed --->", err)
logger.Panicln("please check your network or disable pac mode!")
return err
}
defer resp.Body.Close()

})
err := http.ListenAndServe(":8080", nil)
file, err := os.Create(fileName)
if err != nil {
fmt.Println("start failed --->", err)
logger.Println("create pac file failed --->", err)
return err
}
io.Copy(file, resp.Body)
return nil
}
1 change: 0 additions & 1 deletion fly/relay.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fly

import (
"fmt"
"github.com/xtaci/kcp-go"
"io"
"net"
Expand Down
42 changes: 39 additions & 3 deletions fly/socks5.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fly

import (
"bytes"
"crypto/sha1"
"fmt"
"github.com/xtaci/kcp-go"
Expand Down Expand Up @@ -72,6 +73,13 @@ func handleClient(client net.Conn) {

func Socks5ForClientByTCP(localPort, serverAddr, method, key string) {
listener := ListenTCP(localPort)

cipherEntity := CipherMap[method]
if cipherEntity == nil {
logger.Println("encrypt method: aes-256-cfb")
}else {
logger.Println("encrypt method:", method)
}
for {
client, err := listener.Accept()
if err != nil {
Expand Down Expand Up @@ -119,13 +127,22 @@ func Socks5ForClientByTCP(localPort, serverAddr, method, key string) {

go RelayTraffic(server, client)
RelayTraffic(client, server)
}else {
handlePACRequest(client, buff[:n], localPort)
}
}()
}
}

func Socks5ForServerByTCP(localPort, method, key string) {
listener := ListenTCP(localPort)

cipherEntity := CipherMap[method]
if cipherEntity == nil {
logger.Println("encrypt method: aes-256-cfb")
}else {
logger.Println("encrypt method:", method)
}
for {
logger.Println("waiting...")
client, err := listener.Accept()
Expand All @@ -140,14 +157,14 @@ func Socks5ForServerByTCP(localPort, method, key string) {
if err != nil {
logger.Println("read target address failed --->", err)
return
}else if n < 7 {
} else if n < 7 {
logger.Println("read error of request length --->", buff[:n])
return
}

host, port := parseSocksRequest(buff[:n], n)
//logger.Printf("target server ------\n%s:%s\n------\n%d\n+++++++\n", host, port, buff[:n])
logger.Printf("target server ---> %s:%s <---\n", host, port)
logger.Printf("target server: %s:%s\n", host, port)

// dial the target server
server, err := net.Dial("tcp", net.JoinHostPort(host, port))
Expand Down Expand Up @@ -216,7 +233,7 @@ func Socks5ForServerByUDP(localPort string) {
if err != nil {
logger.Println("read target address failed --->", err)
return
}else if n < 7 {
} else if n < 7 {
logger.Println("read error of request length --->", data[:n])
return
}
Expand Down Expand Up @@ -276,3 +293,22 @@ func parseSocksRequest(data []byte, n int) (string, string) {
port = strconv.Itoa(int(p1)<<8 | int(p2))
return host, port
}

func handlePACRequest(conn net.Conn, buff []byte, port string) {
if bytes.Contains(buff[:], []byte("flynet.pac HTTP")) {
fileBuff, size := GetPAC()
// replace the socks5 port of pac file with the port user choose
fileBuff = bytes.Replace(fileBuff[:size], []byte("SOCKS5 127.0.0.1:1080"), []byte("SOCKS5 127.0.0.1:" + port), 1)

_, _ = conn.Write([]byte(fmt.Sprintf("HTTP/1.1 200 OK\r\n"+
"Content-Type: application/x-ns-proxy-autoconfig\r\n"+
"Server: flynet\r\nContent-Length: %d\r\n\r\n", size)))
_, _ = conn.Write(fileBuff[:size])
}else {
msg := "hello,flynet!"
_, _ = conn.Write([]byte(fmt.Sprintf("HTTP/1.1 200 OK\r\n"+
"Content-Type: text/html; charset=utf-8\r\n"+
"Server: flynet\r\nContent-Length: %d\r\n\r\n%s", len(msg), msg)))
}
conn.Close()
}
13 changes: 9 additions & 4 deletions flynet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,25 @@
# more information at https://github.com/asche910/flynet
#

# if you use flynet in server side, you just care about the the attributes below [server]
[server]
mode = socks5-tcp # work mode
port = 8888 # listen port; multi port use space to divide
method = "aes-256-cfb"
method = aes-256-cfb
password =
verbose = true
log = flynet.log


# if you use flynet in client side, you just care about the the attributes below [client]
[client]
mode = socks5-tcp # work mode
port = 1080 # local socks5 listen port
serverAddr = example.com:8080 # include host and port
method = "aes-256-cfb"
serverAddr = example.com:8888 # include host and port
method = aes-256-cfb
password =
pac-on = true # if true, flynet will start pac mode, and listen at 'http://localhost:pac-port/flynet.pac'(default pac-port is 2080)
pac-port = 2080
pac-update = false # if true, flynet will download the latest pac file from github
verbose = false
# log = flynet.log
# log = flynet.log

0 comments on commit 6911471

Please sign in to comment.