修复断线重连后的bug

添加 proxy protocol v1 的支持
This commit is contained in:
bjdgyc
2020-08-20 19:32:19 +08:00
parent eee99fcb0d
commit bb0de6690a
14 changed files with 858 additions and 50 deletions

View File

@@ -47,6 +47,7 @@ func checkVpnClient(h httprouter.Handle) httprouter.Handle {
// TODO 调试信息输出
// hd, _ := httputil.DumpRequest(r, true)
// fmt.Println("DumpRequest: ", string(hd))
fmt.Println(r.RemoteAddr)
user_Agent := strings.ToLower(r.UserAgent())
x_Aggregate_Auth := r.Header.Get("X-Aggregate-Auth")

View File

@@ -2,6 +2,7 @@ package handler
import (
"encoding/binary"
"fmt"
"log"
"net"
"time"
@@ -9,12 +10,12 @@ import (
"github.com/bjdgyc/anylink/common"
)
func LinkCstp(conn net.Conn, sess *Session) {
func LinkCstp(conn net.Conn, sess *ConnSession) {
// fmt.Println("HandlerCstp")
defer func() {
log.Println("LinkCstp return")
conn.Close()
sess.Close()
log.Println("LinkCstp return")
}()
var (
@@ -47,7 +48,7 @@ func LinkCstp(conn net.Conn, sess *Session) {
// fmt.Println("DISCONNECT")
return
case 0x03: // DPD-REQ
// fmt.Println("DPD-REQ")
fmt.Println("DPD-REQ")
payload := &Payload{
ptype: 0x04, // DPD-RESP
}
@@ -73,11 +74,11 @@ func LinkCstp(conn net.Conn, sess *Session) {
}
}
func cstpWrite(conn net.Conn, sess *Session) {
func cstpWrite(conn net.Conn, sess *ConnSession) {
defer func() {
log.Println("cstpWrite return")
conn.Close()
sess.Close()
log.Println("cstpWrite return")
}()
var (

View File

@@ -29,10 +29,10 @@ func testTun() {
}
// 创建tun网卡
func LinkTun(sess *Session) {
func LinkTun(sess *ConnSession) {
defer func() {
sess.Close()
log.Println("LinkTun return")
sess.Close()
}()
cfg := water.Config{
@@ -84,7 +84,11 @@ func LinkTun(sess *Session) {
}
func tunRead(ifce *water.Interface, sess *Session) {
func tunRead(ifce *water.Interface, sess *ConnSession) {
defer func() {
log.Println("tunRead return")
ifce.Close()
}()
var (
err error
n int

View File

@@ -2,6 +2,7 @@ package handler
import (
"fmt"
"log"
"net/http"
"os"
@@ -19,7 +20,7 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
// TODO 调试信息输出
// hd, _ := httputil.DumpRequest(r, true)
// fmt.Println("DumpRequest: ", string(hd))
// fmt.Println(r.RemoteAddr)
fmt.Println("LinkTunnel", r.RemoteAddr)
// 判断session-token的值
cookie, err := r.Cookie("webvpn")
@@ -35,8 +36,9 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
}
// 开启link
sess.StartLink()
if sess.NetIp == nil {
cSess := sess.StartConn()
if cSess == nil {
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
return
}
@@ -44,14 +46,14 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
// 客户端信息
cstp_mtu := r.Header.Get("X-CSTP-MTU")
master_Secret := r.Header.Get("X-DTLS-Master-Secret")
sess.MasterSecret = master_Secret
sess.Mtu = cstp_mtu
sess.RemoteAddr = r.RemoteAddr
cSess.MasterSecret = master_Secret
cSess.Mtu = cstp_mtu
cSess.RemoteAddr = r.RemoteAddr
w.Header().Set("Server", fmt.Sprintf("%s %s", common.APP_NAME, common.APP_VER))
w.Header().Set("X-CSTP-Version", "1")
w.Header().Set("X-CSTP-Protocol", "Copyright (c) 2004 Cisco Systems, Inc.")
w.Header().Set("X-CSTP-Address", sess.NetIp.String()) // 分配的ip地址
w.Header().Set("X-CSTP-Address", cSess.NetIp.String()) // 分配的ip地址
w.Header().Set("X-CSTP-Netmask", common.ServerCfg.Ipv4Netmask) // 子网掩码
w.Header().Set("X-CSTP-Hostname", hn) // 机器名称
for _, v := range common.ServerCfg.ClientDns {
@@ -115,6 +117,6 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
}
// 开始数据处理
go LinkTun(sess)
go LinkCstp(conn, sess)
go LinkTun(cSess)
go LinkCstp(conn, cSess)
}

View File

@@ -3,11 +3,13 @@ package handler
import (
"crypto/tls"
"fmt"
"github.com/bjdgyc/anylink/proxyproto"
"log"
"net"
"net/http"
"net/http/httputil"
_ "net/http/pprof"
"time"
"github.com/bjdgyc/anylink/common"
"github.com/julienschmidt/httprouter"
@@ -40,13 +42,18 @@ func startTls() {
TLSConfig: tlsConfig,
}
var ln net.Listener
ln, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal(err)
}
defer ln.Close()
srv.SetKeepAlivesEnabled(true)
if common.ServerCfg.ProxyProtocol {
ln = &proxyproto.Listener{Listener: ln, ProxyHeaderTimeout: time.Second * 5}
}
fmt.Println("listen ", addr)
err = srv.ServeTLS(ln, certFile, keyFile)
if err != nil {

View File

@@ -17,27 +17,33 @@ var (
sessions = make(map[string]*Session) // session_token -> SessUser
)
type Session struct {
Sid string // auth返回的 session-id
Token string // session信息的唯一token
DtlsSid string // dtls协议的 session_id
MacAddr string // 客户端mac地址
// 开启link需要设置的参数
// 连接sess
type ConnSession struct {
Sess *Session
MasterSecret string // dtls协议的 master_secret
NetIp net.IP // 分配的ip地址
UserName string // 用户名
RemoteAddr string
Mtu string
TunName string
IsActive bool
LastLogin time.Time
closeOnce sync.Once
Closed chan struct{}
PayloadIn chan *Payload
PayloadOut chan *Payload
}
type Session struct {
Sid string // auth返回的 session-id
Token string // session信息的唯一token
DtlsSid string // dtls协议的 session_id
MacAddr string // 客户端mac地址
UserName string // 用户名
LastLogin time.Time
IsActive bool
// 开启link需要设置的参数
CSess *ConnSession
}
func init() {
rand.Seed(time.Now().UnixNano())
@@ -86,28 +92,37 @@ func NewSession() *Session {
return sess
}
func (s *Session) StartLink() {
func (s *Session) StartConn() *ConnSession {
if s.IsActive == true {
s.CSess.Close()
}
limit := common.LimitClient(s.UserName, false)
if limit == false {
s.NetIp = nil
return
// s.NetIp = nil
return nil
}
s.NetIp = common.AcquireIp(s.MacAddr)
s.IsActive = true
s.closeOnce = sync.Once{}
s.Closed = make(chan struct{})
s.PayloadIn = make(chan *Payload)
s.PayloadOut = make(chan *Payload)
cSess := &ConnSession{
Sess: s,
NetIp: common.AcquireIp(s.MacAddr),
closeOnce: sync.Once{},
Closed: make(chan struct{}),
PayloadIn: make(chan *Payload),
PayloadOut: make(chan *Payload),
}
s.CSess = cSess
return cSess
}
func (s *Session) Close() {
s.closeOnce.Do(func() {
func (cs *ConnSession) Close() {
cs.closeOnce.Do(func() {
log.Println("closeOnce")
close(s.Closed)
s.IsActive = false
s.LastLogin = time.Now()
common.ReleaseIp(s.NetIp, s.MacAddr)
common.LimitClient(s.UserName, true)
close(cs.Closed)
cs.Sess.IsActive = false
cs.Sess.LastLogin = time.Now()
common.ReleaseIp(cs.NetIp, cs.Sess.MacAddr)
common.LimitClient(cs.Sess.UserName, true)
})
}