aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/transport/transport.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/transport/transport.go')
-rw-r--r--src/gnunet/transport/transport.go151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/gnunet/transport/transport.go b/src/gnunet/transport/transport.go
new file mode 100644
index 0000000..14def98
--- /dev/null
+++ b/src/gnunet/transport/transport.go
@@ -0,0 +1,151 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2022 Bernd Fix >Y<
3//
4// gnunet-go is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// gnunet-go is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17// SPDX-License-Identifier: AGPL3.0-or-later
18
19package transport
20
21import (
22 "bytes"
23 "context"
24 "errors"
25 "gnunet/message"
26 "gnunet/util"
27 "net"
28)
29
30// Trnsport layer error codes
31var (
32 ErrTransNoEndpoint = errors.New("no matching endpoint found")
33)
34
35//======================================================================
36// Network-oriented transport implementation
37//======================================================================
38
39// TransportMessage is the unit processed by the transport mechanism.
40// Peer refers to the remote endpoint (sender/receiver) and
41// Msg is the exchanged GNUnet message. The packet itself satisfies the
42// message.Message interface.
43type TransportMessage struct {
44 Hdr *message.Header `` // message header
45 Peer *util.PeerID `` // remote peer
46 Payload []byte `size:"*"` // GNUnet message
47
48 // package-local attributes (transient)
49 msg message.Message
50 endp int // id of endpoint (incoming message)
51 conn int // id of connection (optional, incoming message)
52}
53
54func (msg *TransportMessage) Header() *message.Header {
55 return msg.Hdr
56}
57
58func (msg *TransportMessage) Message() (m message.Message, err error) {
59 if m = msg.msg; m == nil {
60 rdr := bytes.NewBuffer(msg.Payload)
61 m, err = ReadMessageDirect(rdr, nil)
62 }
63 return
64}
65
66// Bytes returns the binary representation of a transport message
67func (msg *TransportMessage) Bytes() ([]byte, error) {
68 buf := new(bytes.Buffer)
69 err := WriteMessageDirect(buf, msg)
70 return buf.Bytes(), err
71}
72
73// String returns the message in human-readable form
74func (msg *TransportMessage) String() string {
75 return "TransportMessage{...}"
76}
77
78// NewTransportMessage creates a message suitable for transfer
79func NewTransportMessage(peer *util.PeerID, payload []byte) (tm *TransportMessage) {
80 if peer == nil {
81 peer = util.NewPeerID(nil)
82 }
83 msize := 0
84 if payload != nil {
85 msize = len(payload)
86 }
87 tm = &TransportMessage{
88 Hdr: &message.Header{
89 MsgSize: uint16(36 + msize),
90 MsgType: message.DUMMY,
91 },
92 Peer: peer,
93 Payload: payload,
94 }
95 return
96}
97
98//----------------------------------------------------------------------
99
100// Transport enables network-oriented (like IP, UDP, TCP or UDS)
101// message exchange on multiple endpoints.
102type Transport struct {
103 incoming chan *TransportMessage // messages as received from the network
104 endpoints map[int]Endpoint // list of available endpoints
105}
106
107// NewTransport creates and runs a new transport layer implementation.
108func NewTransport(ctx context.Context, ch chan *TransportMessage) (t *Transport) {
109 // create transport instance
110 return &Transport{
111 incoming: ch,
112 endpoints: make(map[int]Endpoint),
113 }
114}
115
116// Send a message over suitable endpoint
117func (t *Transport) Send(ctx context.Context, addr net.Addr, msg *TransportMessage) (err error) {
118 for _, ep := range t.endpoints {
119 if ep.CanSendTo(addr) {
120 err = ep.Send(ctx, addr, msg)
121 break
122 }
123 }
124 return
125}
126
127//----------------------------------------------------------------------
128// Endpoint handling
129//----------------------------------------------------------------------
130
131// AddEndpoint instantiates and run a new endpoint handler for the
132// given address (must map to a network interface).
133func (t *Transport) AddEndpoint(ctx context.Context, addr net.Addr) (a net.Addr, err error) {
134 // register endpoint
135 var ep Endpoint
136 if ep, err = NewEndpoint(addr); err != nil {
137 return
138 }
139 t.endpoints[ep.ID()] = ep
140 ep.Run(ctx, t.incoming)
141 return ep.Address(), nil
142}
143
144// Endpoints returns a list of listening addresses managed by transport.
145func (t *Transport) Endpoints() (list []net.Addr) {
146 list = make([]net.Addr, 0)
147 for _, ep := range t.endpoints {
148 list = append(list, ep.Address())
149 }
150 return
151}