Example #1
0
File: tcp.go Project: cirias/myvpn
// Currently one client acceping will block all other clients' request
func (ln *TCPListener) AcceptTCP() (conn *TCPConn, err error) {
	var c net.Conn
	for {
		c, err = ln.Listener.Accept()
		if err != nil {
			glog.Errorln("fail to accept from listener", err)
			return conn, err
		}

		// in case idle connection session being cleaned by NAT server
		if err = c.(*net.TCPConn).SetKeepAlive(true); err != nil {
			glog.Errorln("fail to set keep alive", err)
			return
		}

		req := request{}
		if err := recieve(ln.cipher, c, &req); err != nil {
			glog.Errorln("fail to recieve request", err)
			continue
		}

		if req.Secret != ln.secret {
			send(ln.cipher, c, response{Status: StatusInvalidSecret})
			continue
		}

		ip, err := ln.ipAddrPool.Get()
		if err != nil {
			send(ln.cipher, c, response{Status: StatusNoIPAddrAvaliable})
			continue
		}
		conn = &TCPConn{
			remoteAddr: ip.IP.To4(),
			listener:   ln,
		}

		conn.cipher, err = cipher.NewCipher(req.Key[:])
		if err != nil {
			return conn, err
		}

		res := response{
			Status: StatusOK,
		}
		copy(res.IP[:], ip.IP.To4())
		copy(res.IPMask[:], ip.Mask)
		send(ln.cipher, c, &res)

		conn.Conn = c

		return conn, err
	}
}
Example #2
0
File: tcp.go Project: cirias/myvpn
func ListenTCP(secret, localAddr string, internalIP net.IP, ipNet *net.IPNet) (ln *TCPListener, err error) {
	ln = &TCPListener{}
	ln.Listener, err = net.Listen("tcp", localAddr)
	if err != nil {
		return
	}

	ln.cipher, err = cipher.NewCipher([]byte(secret))
	if err != nil {
		return
	}

	ln.ipAddrPool = NewIPAddrPool(internalIP, ipNet)
	ln.secret = sha256.Sum256([]byte(secret))

	return

}
Example #3
0
File: tcp.go Project: cirias/myvpn
func DialTCP(secret, remoteAddr string) (conn *TCPConn, err error) {
	c, err := net.Dial("tcp", remoteAddr)
	if err != nil {
		glog.Errorln("fail to dial to server", err, remoteAddr)
		return
	}

	// in case idle connection session being cleaned by NAT server
	if err = c.(*net.TCPConn).SetKeepAlive(true); err != nil {
		glog.Errorln("fail to set keep alive", err)
		return
	}

	cph, err := cipher.NewCipher([]byte(secret))
	if err != nil {
		return
	}

	key := make([]byte, cipher.KeySize)
	if _, err = io.ReadFull(rand.Reader, key); err != nil {
		return
	}

	req := request{
		Secret: sha256.Sum256([]byte(secret)),
	}
	copy(req.Key[:], key)

	if err = send(cph, c, &req); err != nil {
		glog.Error("fail to send request", err)
		return
	}

	res := response{}
	if err = recieve(cph, c, &res); err != nil {
		glog.Error("fail to recieve response", err)
		return
	}

	switch res.Status {
	case StatusOK:
	case StatusUnknowErr:
		fallthrough
	case StatusInvalidSecret:
		err = ErrInvalidSecret
		return
	case StatusInvalidProto:
		err = ErrInvalidProto
		return
	case StatusNoIPAddrAvaliable:
		err = ErrNoIPAddrAvaliable
		return
	default:
		err = ErrUnknowErr
		return
	}

	// Initialize conn
	conn = &TCPConn{
		localAddr: res.IP[:],
		ipNetMask: res.IPMask[:],
	}
	conn.Conn = c
	conn.cipher, err = cipher.NewCipher(key)
	return
}