// creates a connection pair (A, B) // they represent the 2 heads of a network connection // so they are interwinded. func NewTestConns() (*TestConn, *TestConn) { connABuf := netutils.NewCircularBuf(2048) connBBuf := netutils.NewCircularBuf(2048) connAReadMutex := &sync.Mutex{} connBReadMutex := &sync.Mutex{} connA := &TestConn{ writeMutex: connBReadMutex, writeBuf: connBBuf, readMutex: connAReadMutex, readBuf: connABuf, connId: "ConnA", closedConn: false} connB := &TestConn{ writeMutex: connAReadMutex, writeBuf: connABuf, readMutex: connBReadMutex, readBuf: connBBuf, connId: "ConnB", closedConn: false} return connA, connB }
func HandleClientConn(rawConn net.Conn, ownKey *rsa.PrivateKey, peerPubKey *rsa.PublicKey) (conn *Conn, err error) { pubKey, privKey, err := box.GenerateKey(rand.Reader) if err != nil { return } keyHash, err := pubKeyHash(&ownKey.PublicKey) if err != nil { return } connRequest := ConnRequest{keyHash, pubKey} reqBytes, err := connRequest.MarshalBinary() if err != nil { return } err = writePubKeyMsg(rawConn, peerPubKey, reqBytes) if err != nil { return } plainReply, err := readPubKeyMsg(rawConn, ownKey) if err != nil { return } var peerSessionKey [sessionKeyLen]byte copy(peerSessionKey[:], plainReply) var sharedKey [sessionKeyLen]byte box.Precompute(&sharedKey, &peerSessionKey, privKey) return &Conn{Conn: rawConn, sharedKey: &sharedKey, readBuf: netutils.NewCircularBuf(readBufferCapacity), readerBufMutex: &sync.Mutex{}}, nil }
func HandleServerConn(rawConn net.Conn, ownKey *rsa.PrivateKey, contacts *ContactList) (conn *Conn, err error) { plain, err := readPubKeyMsg(rawConn, ownKey) connReq := ConnRequest{} err = connReq.UnmarshalBinary(plain) if err != nil { return } contact := contacts.GetContact(connReq.peerPubHash) if contact == nil { return nil, ContactNotFoundError{connReq.peerPubHash[:]} } pubKey, privKey, err := box.GenerateKey(rand.Reader) if err != nil { return } var sharedKey [sessionKeyLen]byte box.Precompute(&sharedKey, connReq.sessionKey, privKey) response := pubKey[:] err = writePubKeyMsg(rawConn, contact.PublicKey, response) return &Conn{Conn: rawConn, sharedKey: &sharedKey, // TODO: circular buffer capacity may cause // streaming to fail. to avoid, // put a cap on the size of the encrypted chunks readBuf: netutils.NewCircularBuf(readBufferCapacity), readerBufMutex: &sync.Mutex{}}, nil }
func TestWriteReadCircularBuf(t *testing.T) { capacity := 10 circ := netutils.NewCircularBuf(capacity) str1 := []byte("wtf") str2 := []byte("omg") var err error err = nil _, err = circ.Write(str1) if err != nil { t.Errorf("failed write %s", err) return } _, err = circ.Write(str2) if err != nil { t.Errorf("failed write %s", err) return } readBuf := make([]byte, 4) byteCount, err := circ.Read(readBuf) if byteCount != 4 || !bytes.Equal(readBuf, []byte("wtfo")) { t.Errorf("read failed") return } str3 := []byte("jeeesus") _, err = circ.Write(str3) if err != nil { t.Errorf("failed write %s", err) return } readBuf = make([]byte, 8) byteCount, err = circ.Read(readBuf) if byteCount != 8 || !bytes.Equal(readBuf, []byte("mgjeeesu")) { t.Errorf("read failed") return } if circ.Size() != 1 { t.Errorf("size is wrong") return } readBuf = make([]byte, 2) byteCount, err = circ.Read(readBuf) fmt.Printf("%i %s", byteCount, string(readBuf)) if byteCount != 1 || !bytes.Equal(readBuf, append([]byte("s"), 0)) { t.Errorf("read failed") return } }