@@ -8,14 +8,19 @@ import (
8
8
"context"
9
9
"fmt"
10
10
"log"
11
+ "log/slog"
11
12
"net/url"
12
13
"os"
13
14
14
15
chclient "github.com/absmach/callhome/pkg/client"
16
+ "github.com/absmach/mgate"
17
+ mgatecoap "github.com/absmach/mgate/pkg/coap"
18
+ "github.com/absmach/mgate/pkg/session"
19
+ mgtls "github.com/absmach/mgate/pkg/tls"
15
20
"github.com/absmach/supermq"
16
21
"github.com/absmach/supermq/coap"
17
22
httpapi "github.com/absmach/supermq/coap/api"
18
- "github.com/absmach/supermq/coap/tracing "
23
+ "github.com/absmach/supermq/coap/middleware "
19
24
smqlog "github.com/absmach/supermq/logger"
20
25
domainsAuthz "github.com/absmach/supermq/pkg/domains/grpcclient"
21
26
"github.com/absmach/supermq/pkg/grpcclient"
@@ -30,19 +35,24 @@ import (
30
35
httpserver "github.com/absmach/supermq/pkg/server/http"
31
36
"github.com/absmach/supermq/pkg/uuid"
32
37
"github.com/caarlos0/env/v11"
38
+ "github.com/pion/dtls/v3"
33
39
"golang.org/x/sync/errgroup"
34
40
)
35
41
36
42
const (
37
- svcName = "coap_adapter"
38
- envPrefix = "SMQ_COAP_ADAPTER_"
39
- envPrefixHTTP = "SMQ_COAP_ADAPTER_HTTP_"
40
- envPrefixCache = "SMQ_COAP_CACHE_"
41
- envPrefixClients = "SMQ_CLIENTS_GRPC_"
42
- envPrefixChannels = "SMQ_CHANNELS_GRPC_"
43
- envPrefixDomains = "SMQ_DOMAINS_GRPC_"
44
- defSvcHTTPPort = "5683"
45
- defSvcCoAPPort = "5683"
43
+ svcName = "coap_adapter"
44
+ envPrefix = "SMQ_COAP_ADAPTER_"
45
+ envPrefixHTTP = "SMQ_COAP_ADAPTER_HTTP_"
46
+ envPrefixCache = "SMQ_COAP_CACHE_"
47
+ envPrefixClients = "SMQ_CLIENTS_GRPC_"
48
+ envPrefixChannels = "SMQ_CHANNELS_GRPC_"
49
+ envPrefixDomains = "SMQ_DOMAINS_GRPC_"
50
+ defSvcHTTPPort = "5683"
51
+ defSvcCoAPPort = "5683"
52
+ targetProtocol = "coap"
53
+ targetCoapHost = "localhost"
54
+ targetCoapPort = "5683"
55
+ targetCoapDtlsPort = "5684"
46
56
)
47
57
48
58
type config struct {
@@ -94,6 +104,13 @@ func main() {
94
104
return
95
105
}
96
106
107
+ dtlsCfg , err := mgtls .NewConfig (env.Options {Prefix : envPrefix })
108
+ if err != nil {
109
+ logger .Error (fmt .Sprintf ("failed to load %s DTLS configuration : %s" , svcName , err ))
110
+ exitCode = 1
111
+ return
112
+ }
113
+
97
114
cacheConfig := messaging.CacheConfig {}
98
115
if err := env .ParseWithOptions (& cacheConfig , env.Options {Prefix : envPrefixCache }); err != nil {
99
116
logger .Error (fmt .Sprintf ("failed to load cache configuration : %s" , err ))
@@ -181,12 +198,12 @@ func main() {
181
198
182
199
svc := coap .New (clientsClient , channelsClient , nps )
183
200
184
- svc = tracing . New (tracer , svc )
201
+ svc = middleware . TracingMiddleware (tracer , svc )
185
202
186
- svc = httpapi .LoggingMiddleware (svc , logger )
203
+ svc = middleware .LoggingMiddleware (svc , logger )
187
204
188
205
counter , latency := prometheus .MakeMetrics (svcName , "api" )
189
- svc = httpapi .MetricsMiddleware (svc , counter , latency )
206
+ svc = middleware .MetricsMiddleware (svc , counter , latency )
190
207
191
208
hs := httpserver .NewServer (ctx , cancel , svcName , httpServerConfig , httpapi .MakeHandler (cfg .InstanceID ), logger )
192
209
@@ -207,7 +224,8 @@ func main() {
207
224
return hs .Start ()
208
225
})
209
226
g .Go (func () error {
210
- return cs .Start ()
227
+ handler := coap .NewHandler (nps , logger , clientsClient , channelsClient , parser )
228
+ return proxyCoAP (ctx , coapServerConfig , dtlsCfg , handler , logger )
211
229
})
212
230
g .Go (func () error {
213
231
return server .StopSignalHandler (ctx , cancel , logger , svcName , hs , cs )
@@ -217,3 +235,43 @@ func main() {
217
235
logger .Error (fmt .Sprintf ("CoAP adapter service terminated: %s" , err ))
218
236
}
219
237
}
238
+
239
+ func proxyCoAP (ctx context.Context , cfg server.Config , dtlsCfg mgtls.Config , handler session.Handler , logger * slog.Logger ) error {
240
+ var err error
241
+ config := mgate.Config {
242
+ Host : cfg .Host ,
243
+ Port : cfg .Port ,
244
+ TargetProtocol : targetProtocol ,
245
+ TargetHost : targetCoapHost ,
246
+ TargetPort : targetCoapPort ,
247
+ }
248
+
249
+ mg := mgatecoap .NewProxy (config , handler , logger )
250
+
251
+ errCh := make (chan error )
252
+
253
+ logger .Info (fmt .Sprintf ("Starting COAP without DTLS proxy on port %s" , cfg .Port ))
254
+ go func () {
255
+ errCh <- mg .Listen (ctx )
256
+ }()
257
+ config .DTLSConfig , err = mgtls .LoadTLSConfig (& dtlsCfg , & dtls.Config {})
258
+ if err != nil {
259
+ return err
260
+ }
261
+
262
+ if config .DTLSConfig != nil {
263
+ config .Port = targetCoapDtlsPort
264
+ mgDtls := mgatecoap .NewProxy (config , handler , logger )
265
+ logger .Info (fmt .Sprintf ("Starting COAP with DTLS proxy on port %s" , cfg .Port ))
266
+ go func () {
267
+ errCh <- mgDtls .Listen (ctx )
268
+ }()
269
+ }
270
+ select {
271
+ case <- ctx .Done ():
272
+ logger .Info (fmt .Sprintf ("proxy COAP shutdown at %s:%s" , config .Host , config .Port ))
273
+ return nil
274
+ case err := <- errCh :
275
+ return err
276
+ }
277
+ }
0 commit comments