diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..60211a35d71a0e28b9275505a2054e678263ffb8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+SHELL := /bin/bash
+REPO := $(shell pwd)
+PROTOC_GEN_GO := $(GOPATH)/bin/protoc-gen-go
+# Protobuf generated go files
+PROTO_FILES = $(shell find . -path ./vendor -prune -o -type f -name '*.proto' -print)
+PROTO_GO_FILES = $(patsubst %.proto, %.pb.go, $(PROTO_FILES))
+
+# If $GOPATH/bin/protoc-gen-go does not exist, we'll run this command to install it.
+$(PROTOC_GEN_GO):
+	(GO111MODULE=off go get -v github.com/golang/protobuf/protoc-gen-go)
+
+# Implicit compile rule for GRPC/proto files
+%.pb.go: %.proto | $(PROTOC_GEN_GO)
+	protoc $< --go_out=plugins=grpc,paths=source_relative:.
+
+.PHONY: compile
+compile: $(PROTO_GO_FILES)
diff --git a/go.mod b/go.mod
index 67b5c1f9ec30356f5fe73e556099f048977649b6..41d778526d789d8bb4185064801a829843d101d0 100644
--- a/go.mod
+++ b/go.mod
@@ -3,13 +3,15 @@ module github.com/iotaledger/goshimmer
 go 1.13
 
 require (
+	github.com/StabbyCutyou/buffstreams v2.0.0+incompatible
 	github.com/dgraph-io/badger v1.6.0
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/gdamore/tcell v1.3.0
 	github.com/go-zeromq/zmq4 v0.6.2
+	github.com/golang/protobuf v1.3.2
 	github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51
 	github.com/gorilla/websocket v1.4.1
-	github.com/iotaledger/autopeering-sim v0.0.0-20191127100001-7ff75c77f051
+	github.com/iotaledger/autopeering-sim v0.0.0-20191201144404-58a6f3b1a56d
 	github.com/iotaledger/hive.go v0.0.0-20191125115115-f88d4ecab6dd
 	github.com/iotaledger/iota.go v1.0.0-beta.10
 	github.com/labstack/echo v3.3.10+incompatible
@@ -24,6 +26,7 @@ require (
 	github.com/spf13/afero v1.2.2 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5
+	github.com/stretchr/testify v1.4.0
 	github.com/valyala/fasttemplate v1.1.0 // indirect
 	go.uber.org/zap v1.13.0
 	golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
diff --git a/go.sum b/go.sum
index cb24f7c52c6e55791c979f9557cbd76c5e64aeeb..756f72664efab54e5926e14a3a1f6ea4ba15f119 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,8 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
 github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
 github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/StabbyCutyou/buffstreams v2.0.0+incompatible h1:7bDqOlL2Ipve3YjZVVrWz/TOVOa+IEHj6XagpAtLn2I=
+github.com/StabbyCutyou/buffstreams v2.0.0+incompatible/go.mod h1:gP6wgxHoC0NrobhUBwx+Y6hx2QyKFOT+ho8619aJCDk=
 github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -109,6 +111,8 @@ github.com/iotaledger/autopeering-sim v0.0.0-20191126125252-956917114dee h1:Lslh
 github.com/iotaledger/autopeering-sim v0.0.0-20191126125252-956917114dee/go.mod h1:JiaqaxLkQVnd8e/sya9y/LlRW56WlRKRl2TQXQCVssI=
 github.com/iotaledger/autopeering-sim v0.0.0-20191127100001-7ff75c77f051 h1:6JWvB/U6C2b92A5Bupnjj6J9KiO0i0AQHQ8RVmMagQo=
 github.com/iotaledger/autopeering-sim v0.0.0-20191127100001-7ff75c77f051/go.mod h1:JiaqaxLkQVnd8e/sya9y/LlRW56WlRKRl2TQXQCVssI=
+github.com/iotaledger/autopeering-sim v0.0.0-20191201144404-58a6f3b1a56d h1:wZoNQRwLj4PqhKfruVQ1Yeci6kaSXnE9nSNCFtJWZ9s=
+github.com/iotaledger/autopeering-sim v0.0.0-20191201144404-58a6f3b1a56d/go.mod h1:JiaqaxLkQVnd8e/sya9y/LlRW56WlRKRl2TQXQCVssI=
 github.com/iotaledger/goshimmer v0.0.0-20191113134331-c2d1b2f9d533/go.mod h1:7vYiofXphp9+PkgVAEM0pvw3aoi4ksrZ7lrEgX50XHs=
 github.com/iotaledger/hive.go v0.0.0-20191118130432-89eebe8fe8eb h1:nuS/LETRJ8obUyBIZeyxeei0ZPlyOMj8YPziOgSM4Og=
 github.com/iotaledger/hive.go v0.0.0-20191118130432-89eebe8fe8eb/go.mod h1:1Thhlil4lHzuy53EVvmEbEvWBFY0Tasp4kCBfxBCPIk=
diff --git a/packages/gossip/buffstreams b/packages/gossip/buffstreams
new file mode 160000
index 0000000000000000000000000000000000000000..20679e9ca31ad9ff33e5a1c3c4b90ec65e9a0b03
--- /dev/null
+++ b/packages/gossip/buffstreams
@@ -0,0 +1 @@
+Subproject commit 20679e9ca31ad9ff33e5a1c3c4b90ec65e9a0b03
diff --git a/packages/gossip/errors.go b/packages/gossip/errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..9ab42437d2f04f91b1f3681663eef149f8ebc388
--- /dev/null
+++ b/packages/gossip/errors.go
@@ -0,0 +1,11 @@
+package gossip
+
+import "errors"
+
+var (
+	errClosed    = errors.New("socket closed")
+	errSender    = errors.New("could not match sender")
+	errRecipient = errors.New("could not match recipient")
+	errSignature = errors.New("could not verify signature")
+	errVersion   = errors.New("protocol version not supported")
+)
diff --git a/packages/gossip/manager.go b/packages/gossip/manager.go
new file mode 100644
index 0000000000000000000000000000000000000000..156156678c340f0744ac1ac658cb2d260a395c17
--- /dev/null
+++ b/packages/gossip/manager.go
@@ -0,0 +1,4 @@
+package gossip
+
+type Manager struct {
+}
diff --git a/packages/gossip/neighbors.go b/packages/gossip/neighbors.go
index 1022ea1071b7a97112efe0c3eea14b98597a5f1e..5e137f5aabd8791549c47b1d984f2d267719ee20 100644
--- a/packages/gossip/neighbors.go
+++ b/packages/gossip/neighbors.go
@@ -1 +1,9 @@
 package gossip
+
+import (
+	"github.com/iotaledger/autopeering-sim/peer"
+)
+
+type Neighbor struct {
+	peer *peer.Peer
+}
diff --git a/packages/gossip/neighbors_test.go b/packages/gossip/neighbors_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d85bf1c11d0544efc8bd13ac428b3d93a4afdcb5
--- /dev/null
+++ b/packages/gossip/neighbors_test.go
@@ -0,0 +1,126 @@
+package gossip
+
+import (
+	"fmt"
+	"log"
+	"strconv"
+	"testing"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/iotaledger/goshimmer/packages/gossip/buffstreams"
+	pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
+)
+
+// TestCallback is a simple server for test purposes. It has a single callback,
+// which is to unmarshall some data and log it.
+func (t *testController) TestCallback(bts []byte) error {
+	msg := &pb.ConnectionRequest{
+		// Version:   1,
+		// From:      "client",
+		// To:        "server",
+		// Timestamp: 1,
+	}
+	err := proto.Unmarshal(bts, msg)
+	if t.enableLogging {
+		fmt.Println(msg.GetFrom(), msg.GetTo())
+	}
+	return err
+}
+
+type testController struct {
+	enableLogging bool
+}
+
+func server() {
+	tc := &testController{
+		enableLogging: true,
+	}
+	cfg := buffstreams.TCPListenerConfig{
+		MaxMessageSize: 2048,
+		EnableLogging:  tc.enableLogging,
+		Address:        buffstreams.FormatAddress("127.0.0.1", strconv.Itoa(5031)),
+		Callback:       tc.TestCallback,
+	}
+	bm := buffstreams.NewManager()
+	err := bm.StartListening(cfg)
+	if err != nil {
+		log.Print(err)
+	} else {
+		// Need to block until ctrl+c, but having trouble getting signal trapping to work on OSX...
+		time.Sleep(time.Second * 2)
+		fmt.Println(bm.GetConnectionIDs())
+	}
+}
+
+func client() {
+	cfg := &buffstreams.TCPConnConfig{
+		MaxMessageSize: 2048,
+		Address:        buffstreams.FormatAddress("127.0.0.1", strconv.Itoa(5031)),
+	}
+	msg := &pb.ConnectionRequest{
+		Version:   1,
+		From:      "client",
+		To:        "server",
+		Timestamp: 1,
+	}
+	msgBytes, err := proto.Marshal(msg)
+	if err != nil {
+		log.Print(err)
+	}
+	//count := 0
+	cbm := buffstreams.NewManager()
+	err = cbm.Dial(cfg)
+	if err != nil {
+		log.Fatal(err)
+	}
+	btw, err := cbm.Write(cfg.Address, msgBytes)
+	//btw, err := buffstreams.DialTCP(cfg)
+	if err != nil {
+		log.Fatal(btw, err)
+	}
+	// currentTime := time.Now()
+	// lastTime := currentTime
+	// for {
+	// 	_, err := btw.Write(msgBytes)
+	// 	if err != nil {
+	// 		fmt.Println("There was an error")
+	// 		fmt.Println(err)
+	// 	}
+	// 	count = count + 1
+	// 	if lastTime.Second() != currentTime.Second() {
+	// 		lastTime = currentTime
+	// 		fmt.Printf(", %d\n", count)
+	// 		count = 0
+	// 	}
+	// 	currentTime = time.Now()
+	// }
+}
+func TestDummy(t *testing.T) {
+	// connections = make(map[string]net.Conn)
+	// makeListener()
+
+	// conn, err := net.Dial("tcp", "localhost:8080")
+	// if err != nil {
+	// 	// handle error
+	// }
+	// testMessage := new(pb.ConnectionRequest)
+	// testMessage.Version = 1
+	// testMessage.From = conn.LocalAddr().String()
+	// testMessage.To = conn.RemoteAddr().String()
+	// testMessage.Timestamp = 1
+	// pkt, err := proto.Marshal(testMessage)
+	// if err != nil {
+	// 	fmt.Println(err)
+	// }
+	// n, err := conn.Write(pkt)
+	// if err != nil {
+	// 	fmt.Println(n, err)
+	// }
+	// //status, err := bufio.NewReader(conn).ReadString('\n')
+	// time.Sleep(4 * time.Second)
+
+	go server()
+	go client()
+	time.Sleep(4 * time.Second)
+}
diff --git a/packages/gossip/proto/message.pb.go b/packages/gossip/proto/message.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..04e2409f0b5236bd63a2f3ce249505c17ac46464
--- /dev/null
+++ b/packages/gossip/proto/message.pb.go
@@ -0,0 +1,165 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: packages/gossip/proto/message.proto
+
+package proto
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type ConnectionRequest struct {
+	// protocol version number
+	Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
+	// string form of the return address (e.g. "192.0.2.1:25", "[2001:db8::1]:80")
+	From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"`
+	// string form of the recipient address
+	To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"`
+	// unix time
+	Timestamp            int64    `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ConnectionRequest) Reset()         { *m = ConnectionRequest{} }
+func (m *ConnectionRequest) String() string { return proto.CompactTextString(m) }
+func (*ConnectionRequest) ProtoMessage()    {}
+func (*ConnectionRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_fcce9e84825f2fa5, []int{0}
+}
+
+func (m *ConnectionRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ConnectionRequest.Unmarshal(m, b)
+}
+func (m *ConnectionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ConnectionRequest.Marshal(b, m, deterministic)
+}
+func (m *ConnectionRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ConnectionRequest.Merge(m, src)
+}
+func (m *ConnectionRequest) XXX_Size() int {
+	return xxx_messageInfo_ConnectionRequest.Size(m)
+}
+func (m *ConnectionRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ConnectionRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ConnectionRequest proto.InternalMessageInfo
+
+func (m *ConnectionRequest) GetVersion() uint32 {
+	if m != nil {
+		return m.Version
+	}
+	return 0
+}
+
+func (m *ConnectionRequest) GetFrom() string {
+	if m != nil {
+		return m.From
+	}
+	return ""
+}
+
+func (m *ConnectionRequest) GetTo() string {
+	if m != nil {
+		return m.To
+	}
+	return ""
+}
+
+func (m *ConnectionRequest) GetTimestamp() int64 {
+	if m != nil {
+		return m.Timestamp
+	}
+	return 0
+}
+
+type SignedConnectionRequest struct {
+	// data of the request
+	Request *ConnectionRequest `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"`
+	// signature of the request
+	Signature            []byte   `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *SignedConnectionRequest) Reset()         { *m = SignedConnectionRequest{} }
+func (m *SignedConnectionRequest) String() string { return proto.CompactTextString(m) }
+func (*SignedConnectionRequest) ProtoMessage()    {}
+func (*SignedConnectionRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_fcce9e84825f2fa5, []int{1}
+}
+
+func (m *SignedConnectionRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SignedConnectionRequest.Unmarshal(m, b)
+}
+func (m *SignedConnectionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SignedConnectionRequest.Marshal(b, m, deterministic)
+}
+func (m *SignedConnectionRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SignedConnectionRequest.Merge(m, src)
+}
+func (m *SignedConnectionRequest) XXX_Size() int {
+	return xxx_messageInfo_SignedConnectionRequest.Size(m)
+}
+func (m *SignedConnectionRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_SignedConnectionRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SignedConnectionRequest proto.InternalMessageInfo
+
+func (m *SignedConnectionRequest) GetRequest() *ConnectionRequest {
+	if m != nil {
+		return m.Request
+	}
+	return nil
+}
+
+func (m *SignedConnectionRequest) GetSignature() []byte {
+	if m != nil {
+		return m.Signature
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*ConnectionRequest)(nil), "proto.ConnectionRequest")
+	proto.RegisterType((*SignedConnectionRequest)(nil), "proto.SignedConnectionRequest")
+}
+
+func init() {
+	proto.RegisterFile("packages/gossip/proto/message.proto", fileDescriptor_fcce9e84825f2fa5)
+}
+
+var fileDescriptor_fcce9e84825f2fa5 = []byte{
+	// 228 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x50, 0x3d, 0x4f, 0xc3, 0x30,
+	0x10, 0x55, 0xd2, 0x42, 0x55, 0xf3, 0x21, 0xe1, 0x05, 0x0f, 0x0c, 0x51, 0x59, 0x32, 0xc5, 0x52,
+	0x11, 0x62, 0x87, 0x7f, 0x60, 0x36, 0x36, 0x37, 0x3d, 0xdc, 0x53, 0xb1, 0x2f, 0xf8, 0x2e, 0xfc,
+	0x7e, 0x54, 0x57, 0x55, 0x87, 0x74, 0x7a, 0x1f, 0x7a, 0xd2, 0x7b, 0x7a, 0xea, 0x79, 0xf0, 0xfd,
+	0xde, 0x07, 0x60, 0x1b, 0x88, 0x19, 0x07, 0x3b, 0x64, 0x12, 0xb2, 0x11, 0x98, 0x7d, 0x80, 0xae,
+	0x28, 0x7d, 0x55, 0x60, 0x45, 0xea, 0xe1, 0x83, 0x52, 0x82, 0x5e, 0x90, 0x92, 0x83, 0xdf, 0x11,
+	0x58, 0xb4, 0x51, 0x8b, 0x3f, 0xc8, 0x8c, 0x94, 0x4c, 0xd5, 0x54, 0xed, 0x9d, 0x3b, 0x49, 0xad,
+	0xd5, 0xfc, 0x3b, 0x53, 0x34, 0x75, 0x53, 0xb5, 0x4b, 0x57, 0xb8, 0xbe, 0x57, 0xb5, 0x90, 0x99,
+	0x15, 0xa7, 0x16, 0xd2, 0x4f, 0x6a, 0x29, 0x18, 0x81, 0xc5, 0xc7, 0xc1, 0xcc, 0x9b, 0xaa, 0x9d,
+	0xb9, 0xb3, 0xb1, 0xda, 0xab, 0xc7, 0x4f, 0x0c, 0x09, 0xb6, 0xd3, 0xda, 0xb5, 0x5a, 0xe4, 0x23,
+	0x2d, 0xb5, 0x37, 0x6b, 0x73, 0xdc, 0xda, 0x4d, 0xa2, 0xee, 0x14, 0x3c, 0x94, 0x31, 0x86, 0xe4,
+	0x65, 0xcc, 0x50, 0x56, 0xdd, 0xba, 0xb3, 0xf1, 0xfe, 0xf6, 0xf5, 0x1a, 0x50, 0x76, 0xe3, 0xa6,
+	0xeb, 0x29, 0x5a, 0x24, 0xf1, 0x3f, 0xb0, 0x0d, 0x90, 0x0f, 0xc7, 0xec, 0x30, 0x46, 0xc8, 0xf6,
+	0xe2, 0x57, 0x9b, 0xeb, 0x02, 0x2f, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd9, 0x68, 0x9e, 0x33,
+	0x4b, 0x01, 0x00, 0x00,
+}
diff --git a/packages/gossip/proto/message.proto b/packages/gossip/proto/message.proto
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7c0ac77a860a17971b6c15a0ce5130a82a18346f 100644
--- a/packages/gossip/proto/message.proto
+++ b/packages/gossip/proto/message.proto
@@ -0,0 +1,26 @@
+syntax = "proto3";
+
+option go_package = "github.com/iotaledger/goshimmer/packages/gossip/proto";
+
+package proto;
+
+//import "peer/proto/peer.proto";
+//import "peer/service/proto/service.proto";
+
+message ConnectionRequest {
+  // protocol version number
+  uint32 version = 1;
+  // string form of the return address (e.g. "192.0.2.1:25", "[2001:db8::1]:80")
+  string from = 2;
+  // string form of the recipient address
+  string to = 3;
+  // unix time
+  int64 timestamp = 4;
+}
+
+message SignedConnectionRequest {
+  // data of the request
+  ConnectionRequest request = 1;
+  // signature of the request
+  bytes signature = 2;
+}
\ No newline at end of file
diff --git a/packages/gossip/protocol.go b/packages/gossip/protocol.go
new file mode 100644
index 0000000000000000000000000000000000000000..7bb6a5f1aeaf9272dc202c18a0db63239fcd0da0
--- /dev/null
+++ b/packages/gossip/protocol.go
@@ -0,0 +1,61 @@
+package gossip
+
+import (
+	"crypto/ed25519"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/iotaledger/autopeering-sim/peer"
+	pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
+)
+
+type Local struct {
+	id  peer.ID
+	key peer.PrivateKey
+}
+
+type Protocol struct {
+	version   uint32
+	local     *Local
+	mgr       *Manager
+	neighbors map[string]*peer.Peer
+}
+
+func sendRequest(p *Protocol, to *peer.Peer) error {
+	msg := &pb.ConnectionRequest{
+		Version:   p.version,
+		From:      p.local.id.String(),
+		To:        to.ID().String(),
+		Timestamp: 1,
+	}
+
+	return nil
+}
+
+func verifyRequest(p *Protocol, msg *pb.ConnectionRequest, signature []byte) error {
+	requester, ok := p.neighbors[msg.GetFrom()]
+	if !ok {
+		return errSender
+	}
+	if msg.GetVersion() != p.version {
+		return errVersion
+	}
+	if msg.GetTo() != p.local.id.String() {
+		return errRecipient
+	}
+	msgBytes, err := proto.Marshal(msg)
+	if err != nil {
+		return err
+	}
+	if !ed25519.Verify(ed25519.PublicKey(requester.PublicKey()), msgBytes, signature) {
+		return errSignature
+	}
+	return nil
+}
+
+func signRequest(key peer.PrivateKey, msg *pb.ConnectionRequest) (signature []byte, err error) {
+	msgByte, err := proto.Marshal(msg)
+	if err != nil {
+		return signature, err
+	}
+	return ed25519.Sign(ed25519.PrivateKey(key), msgByte), nil
+}
diff --git a/packages/gossip/protocol_test.go b/packages/gossip/protocol_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..2ee0d77ee3ac665b2f39121714c5c48a61216b56
--- /dev/null
+++ b/packages/gossip/protocol_test.go
@@ -0,0 +1,50 @@
+package gossip
+
+import (
+	"crypto/ed25519"
+	"fmt"
+	"testing"
+
+	"github.com/iotaledger/autopeering-sim/peer"
+	"github.com/iotaledger/autopeering-sim/peer/service"
+	pb "github.com/iotaledger/goshimmer/packages/gossip/proto"
+)
+
+const (
+	testNetwork = "tcp"
+	testAddress = "127.0.0.1:8000"
+)
+
+func newTestServiceRecord() *service.Record {
+	services := service.New()
+	services.Update(service.PeeringKey, testNetwork, testAddress)
+	return services
+}
+
+func TestVerifyRequest(t *testing.T) {
+	pubA, privA, _ := ed25519.GenerateKey(nil)
+	pubB, privB, _ := ed25519.GenerateKey(nil)
+	peerA := &Local{
+		id:  peer.PublicKey(pubA).ID(),
+		key: peer.PrivateKey(privA),
+	}
+	peerB := peer.NewPeer(peer.PublicKey(pubB), newTestServiceRecord())
+	p := &Protocol{
+		version: 1,
+		local:   peerA,
+		neighbors: map[string]*peer.Peer{
+			peerB.ID().String(): peerB,
+		},
+	}
+	msg := &pb.ConnectionRequest{
+		Version:   1,
+		From:      peerB.ID().String(),
+		To:        peerA.id.String(),
+		Timestamp: 1,
+	}
+	signature, _ := signRequest(peer.PrivateKey(privB), msg)
+	err := verifyRequest(p, msg, signature)
+	if err != nil {
+		fmt.Println("Error:", err)
+	}
+}
diff --git a/packages/gossip/transport/transport.go b/packages/gossip/transport/transport.go
new file mode 100644
index 0000000000000000000000000000000000000000..af9cd84f082bad37a940f57b211fff20bace9317
--- /dev/null
+++ b/packages/gossip/transport/transport.go
@@ -0,0 +1,25 @@
+package transport
+
+const (
+	// MaxPacketSize specifies the maximum allowed size of packets.
+	// Packets larger than this will be cut and thus treated as invalid.
+	MaxPacketSize = 1280
+)
+
+// Transport is generic network connection to transfer protobuf packages.
+// Multiple goroutines may invoke methods on a Conn simultaneously.
+type Transport interface {
+	// ReadFrom reads a packet from the connection. It returns the package and
+	// the return address for that package in string form.
+	ReadFrom() (pkt []byte, address string, err error)
+
+	// WriteTo writes a packet to the string encoded target address.
+	WriteTo(pkt []byte, address string) error
+
+	// Close closes the transport layer.
+	// Any blocked ReadFrom or WriteTo operations will return errors.
+	Close()
+
+	// LocalAddr returns the local network address in string form.
+	LocalAddr() string
+}