func tcpClient(addr string, key, message []byte) ([]byte, error) { tcpaddr, err := net.ResolveTCPAddr("tcp", addr) if err != nil { return nil, err } ciphertext, err := libsodium.EncryptData(key, message) if err != nil { return nil, err } tcpconn, err := net.DialTCP("tcp", nil, tcpaddr) if err != nil { return nil, err } defer tcpconn.Close() tcpconn.SetWriteDeadline(time.Now().Add(time.Duration(20) * time.Second)) _, err = tcpconn.Write(netstring.Marshall(ciphertext)) if err != nil { return nil, err } tcpconn.SetReadDeadline(time.Now().Add(time.Duration(20) * time.Second)) bufReader := bufio.NewReader(tcpconn) var buf bytes.Buffer var ip []byte for { rData, err := bufReader.ReadBytes(',') if err != nil { if err == io.EOF { return nil, err } buf.Write(rData) continue } buf.Write(rData) ip, err = netstring.Unmarshall(buf.Bytes()) if err != nil { if err == netstring.ErrNsLenNotEqaulOrgLen { continue } return nil, err } break } return ip, nil }
func handleTCPConn(tcpconn *net.TCPConn, encryptKey []byte, buffer *bytes.Buffer, bpool *bpool.SizedBufferPool) { defer tcpconn.Close() defer bpool.Put(buffer) var receiveData []byte //tcpconn need read all data in 20 second ,otherwise Timeout() will be true tcpconn.SetReadDeadline(time.Now().Add(time.Duration(20) * time.Second)) bufReader := bufio.NewReader(tcpconn) for { rData, err := bufReader.ReadBytes(',') if err != nil { if err == io.EOF { log.Printf("TCPConn Read error\n") return } buffer.Write(rData) continue } buffer.Write(rData) receiveData, err = netstring.Unmarshall(buffer.Bytes()) if err != nil { if err == netstring.ErrNsLenNotEqaulOrgLen { continue } else { log.Printf("netstring unmarshall error : %v\n", err) return } } break } _, err := libsodium.DecryptData(encryptKey, receiveData) if err != nil { log.Printf("tcp DecryptData error : %v\n", err) return } tcpconn.SetWriteDeadline(time.Now().Add(time.Duration(20) * time.Second)) _, err = tcpconn.Write(netstring.Marshall([]byte(homeip))) if err != nil { log.Printf("tcpconn error : %v\n", err) } }
func TestTcpServe(t *testing.T) { key := make([]byte, 32) copy(key, "this is my key value!") //go server.TcpServe("localhost:8080", key) tcpaddr, err := net.ResolveTCPAddr("tcp", "localhost:8080") if err != nil { t.Fatalf("ResolveTCPAddr error : %v\n", err) } tcpconn, err := net.DialTCP("tcp", nil, tcpaddr) if err != nil { t.Fatalf("DialTCP error : %v\n", err) } defer tcpconn.Close() //tcpconn.SetDeadline(time.Now().Add(time.Duration(10) * time.Second)) plaintext := []byte("this is plaintext") ciphertext, err := server.EncryptData(key, plaintext, nil) if err != nil { t.Fatalf("EncryptData error : %v\n", err) } bufWriter := bufio.NewWriter(tcpconn) t.Logf("ciphertext is %x\n", ciphertext) marshall := netstring.Marshall(ciphertext) t.Logf("marshall data is %x, len is %d\n", marshall, len(marshall)) _, err = bufWriter.Write(marshall) if err != nil { t.Fatalf("Write error : %v\n", err) } bufWriter.Flush() tcpconn.CloseWrite() rdata := make([]byte, 50) rlen, err := tcpconn.Read(rdata) if err != nil { t.Fatalf("Read error : %v\n", err) } else { t.Logf("return data is %s\n", rdata[:rlen]) } }
func udpClient(addr string, key, message []byte) error { udpaddr, err := net.ResolveUDPAddr("udp", addr) if err != nil { return err } ciphertext, err := libsodium.EncryptData(key, message) if err != nil { return err } udpconn, err := net.DialUDP("udp", nil, udpaddr) if err != nil { return err } defer udpconn.Close() _, err = udpconn.Write(netstring.Marshall(ciphertext)) if err != nil { return err } return nil }