// 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 } }
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 }
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 }