コード例 #1
0
ファイル: multiplexer.go プロジェクト: xyz12810/deblocus
// TODO notify peer to slow down when queue increased too fast
func (p *multiplexer) Listen(tun *Conn, handler event_handler, interval int) error {
	tun.priority = &TSPriority{0, 1e9}
	p.pool.Push(tun)
	defer p.onTunDisconnected(tun, handler)
	tun.SetSockOpt(1, 0, 1)
	var (
		header = make([]byte, FRAME_HEADER_LEN)
		idle   = NewIdler(interval, p.isClient)
		router = p.router
		nr     int
		er     error
		frm    *frame
		key    string
	)
	if !p.isClient {
		// server first ping client
		// make client aware of using a valid token.
		idle.ping(tun)
	}
	for {
		idle.newRound(tun)
		nr, er = io.ReadFull(tun, header)
		if nr == FRAME_HEADER_LEN {
			frm, er = parse_frame(header)
			if er == nil && len(frm.data) > 0 {
				// read All and discard tail random
				nr, er = io.ReadFull(tun, frm.data)
				frm.data = frm.data[:frm.length]
			}
		}
		if er != nil {
			// shutdown
			if atomic.LoadInt32(&p.status) < 0 {
				time.Sleep(time.Second)
				return nil
			}
			switch idle.consumeError(er) {
			case ERR_NEW_PING:
				if er = idle.ping(tun); er == nil {
					continue
				}
			case ERR_PING_TIMEOUT:
				er = ex.New("Peer was unresponsive then close")
			}
			// abandon this connection
			return er
		}
		// prefix tun.identifier
		key = sessionKey(tun, frm.sid)

		switch frm.action {
		case FRAME_ACTION_CLOSE_W:
			if edge, _ := router.getRegistered(key); edge != nil {
				edge.bitwiseCompareAndSet(TCP_CLOSE_W)
				edge.deliver(frm)
			}

		case FRAME_ACTION_CLOSE_R:
			if edge, _ := router.getRegistered(key); edge != nil {
				edge.bitwiseCompareAndSet(TCP_CLOSE_R)
				closeR(edge.conn)
			}

		case FRAME_ACTION_DATA:
			edge, pre := router.getRegistered(key)
			if edge != nil {
				edge.deliver(frm)
			} else if pre {
				router.preDeliver(key, frm)
			} else {
				if log.V(log.LV_WARN) {
					log.Warningln("Peer sent data to an unexisted socket.", key, frm)
				}
				// trigger sending close to notice peer.
				pack(header, FRAME_ACTION_CLOSE_R, frm.sid, nil)
				if er = frameWriteBuffer(tun, header); er != nil {
					return er
				}
			}

		case FRAME_ACTION_OPEN:
			router.preRegister(key)
			p.wg.Add(1)
			go p.connectToDest(frm, key, tun)

		case FRAME_ACTION_OPEN_N, FRAME_ACTION_OPEN_Y, FRAME_ACTION_OPEN_DENIED:
			edge, _ := router.getRegistered(key)
			if edge != nil {
				if log.V(log.LV_ACT_FRM) {
					log.Infoln(p.role, "received OPEN_x", frm)
				}
				edge.ready <- frm.action
				close(edge.ready)
			} else {
				if log.V(log.LV_WARN) {
					log.Warningln("Peer sent OPEN_x to an unexisted socket.", key, frm)
				}
			}

		case FRAME_ACTION_PING:
			if er = idle.pong(tun); er == nil {
				atomic.AddInt32(&p.pingCnt, 1)
			} else { // reply pong failed
				return er
			}

		case FRAME_ACTION_PONG:
			if idle.verify() {
				if p.isClient && idle.lastPing > 0 {
					sRtt, devRtt := idle.updateRtt()
					atomic.StoreInt32(&p.sRtt, sRtt)
					if DEBUG {
						log.Infof("sRtt=%d devRtt=%d", sRtt, devRtt)
						if devRtt+(sRtt>>2) > sRtt {
							// restart ???
							log.Warningf("Network jitter sRtt=%d devRtt=%d", sRtt, devRtt)
						}
					}
				}
			} else {
				log.Warningln("Incorrect action_pong received")
			}

		case FRAME_ACTION_TOKENS:
			handler(evt_tokens, frm.data)

		default: // impossible
			return fmt.Errorf("Unrecognized %s", frm)
		}
		tun.Update()
	}
}
コード例 #2
0
ファイル: cipher.go プロジェクト: noscripter/deblocus
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/asn1"
	"fmt"
	"io"
	"math/big"
	"strings"

	"github.com/Lafeng/deblocus/crypto"
	"github.com/Lafeng/deblocus/exception"
)

var (
	UNSUPPORTED_CIPHER = exception.New("Unsupported cipher")
)

type cipherBuilder func(k, iv []byte) *XORCipherKit

type cipherDesc struct {
	keyLen  int
	ivLen   int
	builder cipherBuilder
}

type cipherKit interface {
	encrypt(dst, src []byte)
	decrypt(dst, src []byte)
	Cleanup()
}
コード例 #3
0
ファイル: multiplexer.go プロジェクト: xyz12810/deblocus
	ERR_NEW_PING     = 0xf
	ERR_UNKNOWN      = 0x0
)

const sid_max uint32 = 0xffff

var (
	// [1, 0xfffe]
	sid_seq      uint32
	bytePoolOnce sync.Once
	bytePool     *bytepool.BytePool
	dialer       *Dialer
)

var (
	ERR_TUN_NA        = ex.New("No tunnels are available")
	ERR_DATA_TAMPERED = ex.New("data tampered")
)

// --------------------
// event_handler
// --------------------
type event byte

const (
	evt_tokens = event(1)
)

type event_handler func(e event, msg ...interface{})

// --------------------
コード例 #4
0
ファイル: proxy.go プロジェクト: noscripter/deblocus
const (
	PROT_UNKNOWN = 1
	PROT_SOCKS5  = 2
	PROT_HTTP    = 3
	PROT_HTTP_T  = 4
	PROT_LOCAL   = 5
)

const (
	HTTP_PROXY_STATUS_LINE = "HTTP/1.1 200 Connection established"
	CRLF                   = "\r\n"
)

var (
	// socks5 exceptions
	INVALID_SOCKS5_HEADER = exception.New("Invalid socks5 header")
	HOST_UNREACHABLE      = exception.New("Host is unreachable")
)

// socks5 protocol handler in client side
// Ref: https://www.ietf.org/rfc/rfc1928.txt
type socks5Handler struct {
	conn net.Conn
}

// step1-2
func (s socks5Handler) handshake() bool {
	var buf = make([]byte, 2)
	var n, nmethods int
	var ver byte
	setRTimeout(s.conn)
コード例 #5
0
ファイル: client.go プロジェクト: noscripter/deblocus
)

const (
	DT_PING_INTERVAL = 110
	RETRY_INTERVAL   = time.Second * 5
	REST_INTERVAL    = RETRY_INTERVAL
)

const (
	CLT_CLOSED  int32 = -1
	CLT_WORKING int32 = 0
	CLT_PENDING int32 = 1
)

var (
	ERR_REQ_TK_TIMEOUT = ex.New("Request token timeout")
	ERR_REQ_TK_ABORTED = ex.New("Requst token aborted")
)

type Client struct {
	mux       *multiplexer
	token     []byte
	params    *tunParams
	connInfo  *connectionInfo
	lock      sync.Locker
	dtCnt     int32
	reqCnt    int32
	state     int32
	round     int32
	pendingTK *timedWait
}
コード例 #6
0
ファイル: d5.go プロジェクト: ghmajx/deblocus
	CRLF                = "\r\n"
	IDENTITY_SEP        = "\x00"
	HTTP_PROXY_VER_LINE = "HTTP/1.1 200 Connection established"
	HTTP_PROXY_AGENT    = "Proxy-Agent: "
)

var (
	// for main package injection
	VERSION    uint32
	VER_STRING string
	DEBUG      bool
)

var (
	// socks5 exceptions
	INVALID_SOCKS5_HEADER  = exception.New(0xff, "Invalid socks5 header")
	INVALID_SOCKS5_REQUEST = exception.New(0x07, "Invalid socks5 request")
	GENERAL_FAILURE        = exception.New(0x01, "General failure")
	HOST_UNREACHABLE       = exception.New(0x04, "Host is unreachable")
)

var (
	// D5 exceptions
	INVALID_D5PARAMS     = exception.NewW("Invalid D5Params")
	D5SER_UNREACHABLE    = exception.NewW("D5Server is unreachable")
	VALIDATION_FAILED    = exception.NewW("Validation failed")
	NEGOTIATION_FAILED   = exception.NewW("Negotiation failed")
	DATATUN_SESSION      = exception.NewW("DT")
	INCONSISTENT_HASH    = exception.NewW("Inconsistent hash")
	INCOMPATIBLE_VERSION = exception.NewW("Incompatible version")
	UNRECOGNIZED_REQ     = exception.NewW("Unrecognized Request")
コード例 #7
0
ファイル: d5.go プロジェクト: noscripter/deblocus
	TIME_ERROR = 1  // minutes

	NULL         = ""
	IDENTITY_SEP = "\x00"
)

var (
	// for main package injection
	VERSION    uint32
	VER_STRING string
	DEBUG      bool
)

var (
	// D5 exceptions
	ILLEGAL_STATE        = exception.New("Invalid State")
	VALIDATION_FAILED    = exception.New("Validation Failed")
	INCONSISTENT_HASH    = exception.New("Inconsistent Hashsum")
	INCOMPATIBLE_VERSION = exception.New("Incompatible Version")
	UNRECOGNIZED_REQ     = exception.New("Unrecognized Request")
	ERR_TIME_ERROR       = exception.New("Time Error")
	ABORTED_ERROR        = exception.New("")
)

// len_inByte enum: 1,2,4
func ReadFullByLen(len_inByte int, reader io.Reader) (buf []byte, err error) {
	lb := make([]byte, len_inByte)
	_, err = io.ReadFull(reader, lb)
	if err != nil {
		return
	}
コード例 #8
0
ファイル: config.go プロジェクト: xyz12810/deblocus
	CF_CLIENT     = "deblocus.Client"
	CF_SERVER     = "deblocus.Server"
	CF_URL        = "URL"
	CF_KEY        = "Key"
	CF_CRYPTO     = "Crypto"
	CF_PRIVKEY    = "PrivateKey"
	CF_CREDENTIAL = "Credential"
	CF_PAC        = "PAC.Server"
	CF_FILE       = "File"

	CONFIG_NAME = "deblocus.ini"
	SIZE_UNIT   = "BKMG"
)

var (
	UNRECOGNIZED_SYMBOLS = exception.New("Unrecognized symbols")
	LOCAL_BIND_ERROR     = exception.New("Local bind error")
	CONF_MISS            = exception.New("Missed field in config:")
	CONF_ERROR           = exception.New("Error field in config:")
)

type ServerRole uint32

const (
	SR_AUTO   ServerRole = ^ServerRole(0)
	SR_CLIENT ServerRole = 0x0f
	SR_SERVER ServerRole = 0xf0
)

type ConfigMan struct {
	filepath    string
コード例 #9
0
ファイル: auth.go プロジェクト: noscripter/deblocus
package auth

import (
	"strings"

	"github.com/Lafeng/deblocus/exception"
)

var (
	NO_SUCH_USER          = exception.New("No such user")
	AUTH_FAILED           = exception.New("Auth failed")
	UNIMPLEMENTED_AUTHSYS = exception.New("Unimplemented authsys")
	INVALID_AUTH_CONF     = exception.New("Invalid Auth config")
	INVALID_AUTH_PARAMS   = exception.New("Invalid Auth params")
)

type AuthSys interface {
	Authenticate(user, passwd string) (bool, error)
	AddUser(user *User) error
	UserInfo(user string) (*User, error)
}

type User struct {
	Name string
	Pass string
}

func GetAuthSysImpl(proto string) (AuthSys, error) {
	sep := strings.Index(proto, "://")
	if sep > 0 {
		switch proto[:sep] {
コード例 #10
0
ファイル: dh.go プロジェクト: angle1895/deblocus
package crypto

import (
	"crypto/elliptic"
	"crypto/rand"
	"github.com/Lafeng/deblocus/exception"
	"github.com/monnand/dhkx"
	"math/big"
	"strings"
)

var (
	NoSuchDHMethod  = exception.New(0, "No Such DH method")
	InvalidECCParam = exception.New(0, "Invalid ECC parameters")
)

// enum: DHE, ECDHE-P224,256,384,521
func NewDHKey(name string) (DHKE, error) {
	name = strings.ToUpper(name)
	if name == "DHE" {
		return GenerateDHEKey()
	}
	if strings.HasPrefix(name, "ECDHE-") {
		name = name[6:]
	}
	var curve elliptic.Curve
	switch name {
	case "P224":
		curve = elliptic.P224()
	case "P256":
		curve = elliptic.P256()