Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mpx 24 coap #1

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Mpx 24 coap #1

wants to merge 10 commits into from

Conversation

felixgateru
Copy link
Owner

@felixgateru felixgateru commented Apr 24, 2024

Pull request title should be MF-XXX - description or NOISSUE - description where XXX is ID of issue that this PR relate to.
Please review the CONTRIBUTING.md file for detailed contributing guidelines.

What does this do?

Which issue(s) does this PR fix/relate to?

Put here Resolves #XXX to auto-close the issue that your PR fixes (if such)

List any changes that modify/break current functionality

Have you included tests for your changes?

Did you document any new/modified functionality?

Notes

Summary by CodeRabbit

  • New Features

    • Introduced CoAP functionality to existing MQTT and HTTP proxy servers, supporting both DTLS and non-DTLS configurations.
    • Added example scripts for CoAP communication with and without DTLS.
    • Implemented a CoAP server example for handling requests.
  • Bug Fixes

    • Corrected variable names and paths in the environment configuration for consistency.
  • Documentation

    • Enhanced the README.md with detailed setup instructions and new CoAP configurations.
  • Refactor

    • Renamed PREFIX_PATH variables to PATH_PREFIX for various protocols.
    • Refactored TLS configuration handling to support both TLS and DTLS.
  • Chores

    • Added new dependencies for CoAP and DTLS support.

Copy link

coderabbitai bot commented Apr 24, 2024

Walkthrough

The recent updates enhance the mProxy application by introducing CoAP functionality, supporting both DTLS (Datagram Transport Layer Security) and non-DTLS communication. Key improvements include renaming configuration variables for consistency and adding comprehensive examples for CoAP clients and servers. These changes significantly improve security, flexibility, and usability, marking a notable advancement in protocol handling.

Changes

Files/Paths Change Summary
.env, README.md Renamed PREFIX_PATH variables to PATH_PREFIX and added new CoAP configurations.
cmd/main.go, config.go Introduced CoAP functionality and updated config with DTLS configurations.
examples/client/coap/with_dtls.sh, without_dtls.sh Added scripts demonstrating CoAP client usage with and without DTLS.
examples/server/coap/main.go Implemented a CoAP server example.
pkg/coap/coap.go Added CoAP proxy functionality with support for DTLS.
pkg/mqtt/mqtt.go, pkg/mqtt/websocket/websocket.go Renamed New function to NewProxy for clarity and updated path prefix references.
pkg/tls/tls.go Introduced TLSConfig interface to support both TLS and DTLS configurations.
go.mod Updated dependencies to include new libraries for DTLS and CoAP support.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant mProxy
    participant CoAPServer

    Client->>mProxy: Send CoAP Request
    mProxy->>CoAPServer: Forward Request
    CoAPServer-->>mProxy: Send Response
    mProxy-->>Client: Forward Response
Loading

Poem

In the realm of bytes and streams,
CoAP joins the proxy dreams.
With DTLS, secure and bright,
Messages traverse the night.
Paths renamed, configs aligned,
A proxy evolution, finely designed.
Hopping forward, code refined,
In mProxy, new strengths combined. 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

README.md Outdated
Comment on lines 133 to 127
- mProxy server for `COAP protocol without DTLS` on port `5682`
- mProxy server for `COAP protocol with DTLS` on port `5684`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistent capitalization for protocol names.

-   - mProxy server for `COAP protocol without DTLS` on port `5682` 
-   - mProxy server for `COAP protocol with DTLS` on port `5684`
+   - mProxy server for `CoAP protocol without DTLS` on port `5682` 
+   - mProxy server for `CoAP protocol with DTLS` on port `5684`

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
- mProxy server for `COAP protocol without DTLS` on port `5682`
- mProxy server for `COAP protocol with DTLS` on port `5684`
- mProxy server for `CoAP protocol without DTLS` on port `5682`
- mProxy server for `CoAP protocol with DTLS` on port `5684`

pkg/tls/tls.go Outdated
Comment on lines 34 to 38
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{*certificate},
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing MinVersion in TLS configuration.

- Certificates: []tls.Certificate{*certificate},
+ Certificates: []tls.Certificate{*certificate}, MinVersion: tls.VersionTLS13

Please add MinVersion: tls.VersionTLS13 to the TLS configuration to ensure the use of a secure TLS version.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{*certificate},
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{*certificate}, MinVersion: tls.VersionTLS13
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

pkg/tls/tls.go Outdated
// Load return a TLS configuration that can be used in TLS servers.
func Load(c *Config) (*tls.Config, error) {
// LoadTLS returns a TLS configuration that can be used in TLS servers.
func LoadTLS(c *Config) (*tls.Config, error) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure MinVersion is set in the TLS configuration to enforce a secure protocol version.

- tlsConfig = &tls.Config{
-   Certificates: []tls.Certificate{certificate},
- }
+ tlsConfig = &tls.Config{
+   Certificates: []tls.Certificate{certificate},
+   MinVersion: tls.VersionTLS13,
+ }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func LoadTLS(c *Config) (*tls.Config, error) {
func LoadTLS(c *Config) (*tls.Config, error) {
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{certificate},
MinVersion: tls.VersionTLS13,
}

pkg/tls/tls.go Outdated
@@ -69,6 +71,56 @@
return tlsConfig, nil
}

// LoadDTLS returns a DTLS configuration that can be used in DTLS servers.
func LoadDTLS(c *Config) (*dtls.Config, error) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure MinVersion is set in the DTLS configuration to enforce a secure protocol version.

- dtlsConfig = &dtls.Config{
-   Certificates: []tls.Certificate{certificate},
- }
+ dtlsConfig = &dtls.Config{
+   Certificates: []tls.Certificate{certificate},
+   MinVersion: dtls.VersionDTLS12,
+ }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func LoadDTLS(c *Config) (*dtls.Config, error) {
func LoadDTLS(c *Config) (*dtls.Config, error) {
dtlsConfig = &dtls.Config{
Certificates: []tls.Certificate{certificate},
MinVersion: dtls.VersionDTLS12,
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

config.go Outdated
Comment on lines 32 to 36
c.TLSConfig, err = mptls.LoadSecConfig(&cfg, &tls.Config{})
if err != nil {
return Config{}, err
}
c.DTLSConfig, err = mptls.LoadSecConfig(&cfg, &dtls.Config{})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the minimum version for TLS is set to TLS 1.3 to enhance security. This change is necessary to comply with best practices for secure communication.

- c.TLSConfig, err = mptls.LoadSecConfig(&cfg, &tls.Config{})
+ c.TLSConfig, err = mptls.LoadSecConfig(&cfg, &tls.Config{MinVersion: tls.VersionTLS13})

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
c.TLSConfig, err = mptls.LoadSecConfig(&cfg, &tls.Config{})
if err != nil {
return Config{}, err
}
c.DTLSConfig, err = mptls.LoadSecConfig(&cfg, &dtls.Config{})
c.TLSConfig, err = mptls.LoadSecConfig(&cfg, &tls.Config{MinVersion: tls.VersionTLS13})
if err != nil {
return Config{}, err
}
c.DTLSConfig, err = mptls.LoadSecConfig(&cfg, &dtls.Config{})

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Out of diff range and nitpick comments (1)
README.md (1)

Line range hint 65-65: Correct the possessive pronoun to enhance grammatical accuracy.

- alongside with it's [`main()` function](cmd/main.go).
+ alongside with its [`main()` function](cmd/main.go).
Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 4efdea9 and db56b4b.
Files selected for processing (4)
  • README.md (10 hunks)
  • examples/client/coap/with_dtls.sh (1 hunks)
  • examples/client/coap/without_dtls.sh (1 hunks)
  • pkg/coap/coap.go (1 hunks)
Files skipped from review due to trivial changes (1)
  • examples/client/coap/without_dtls.sh
Additional Context Used
LanguageTool (19)
README.md (19)

Near line 65: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...iven here, alongside with it's main() function. ...


Near line 65: Did you mean the possessive pronoun “its”?
Context: ...mples/simple/simple.go), alongside with it's main() function. ## D...


Near line 72: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...s a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node...


Near line 199: Use the singular noun “script” with the word ‘This’.
Context: ...ervers running for CoAP protocols. This scripts can be used after changing the `MPROXY_...


Near line 281: Loose punctuation mark.
Context: ...tion Environment Variables - ADDRESS : Specifies the address at which mProxy w...


Near line 282: Loose punctuation mark.
Context: ...HTTP proxy connections. - PATH_PREFIX : Defines the path prefix when listening ...


Near line 283: Loose punctuation mark.
Context: ...bSocket or HTTP connections. - TARGET : Specifies the address of the target ser...


Near line 287: Loose punctuation mark.
Context: ...on Environment Variables - CERT_FILE : Path to the TLS certificate file. - `KE...


Near line 288: Loose punctuation mark.
Context: ... the TLS certificate file. - KEY_FILE : Path to the TLS certificate key file. -...


Near line 289: Loose punctuation mark.
Context: ...ertificate key file. - SERVER_CA_FILE : Path to the Server CA certificate file....


Near line 290: Loose punctuation mark.
Context: ...CA certificate file. - CLIENT_CA_FILE : Path to the Client CA certificate file....


Near line 291: Loose punctuation mark.
Context: ...ate file. - CERT_VERIFICATION_METHODS : Methods for validating certificates. Ac...


Near line 297: Loose punctuation mark.
Context: ...n Environment Variables - OCSP_DEPTH : Depth of client certificate verificatio...


Near line 298: Loose punctuation mark.
Context: ...es are verified. - OCSP_RESPONDER_URL : Override value for the OCSP responder U...


Near line 302: Loose punctuation mark.
Context: ...ion Environment Variables - CRL_DEPTH: Depth of client certificate verificatio...


Near line 303: Loose punctuation mark.
Context: ...s verified. - CRL_DISTRIBUTION_POINTS : Override for the CRL Distribution Point...


Near line 304: Loose punctuation mark.
Context: ...L_DISTRIBUTION_POINTS_ISSUER_CERT_FILE` : Path to the issuer certificate file for...


Near line 305: Loose punctuation mark.
Context: ...TRIBUTION_POINTS. - OFFLINE_CRL_FILE` : Path to the offline CRL file, which can...


Near line 306: Loose punctuation mark.
Context: ...ction. - OFFLINE_CRL_ISSUER_CERT_FILE : Location of the issuer certificate file...

GitHub Check Runs (1)
Lint and Build failure (5)

pkg/coap/coap.go: [failure] 104-104:
slog: slog.Logger.Error arg "err" should be a string or a slog.Attr (possible missing key or value) (govet)


pkg/coap/coap.go: [failure] 124-124:
slog: slog.Logger.Error arg "err" should be a string or a slog.Attr (possible missing key or value) (govet)


pkg/coap/coap.go: [failure] 131-131:
slog: slog.Logger.Error arg "err" should be a string or a slog.Attr (possible missing key or value) (govet)

Additional comments not posted (15)
examples/client/coap/with_dtls.sh (3)

14-15: Command uses environment variables for certificate paths, enhancing flexibility and security.


18-18: Command correctly uses environment variables for certificate paths.


25-25: Command correctly uses hardcoded paths for invalid certificates to test error handling.

pkg/coap/coap.go (7)

44-52: Method correctly constructs and sends CoAP error messages, ensuring proper resource management.


54-79: Ensure robust error handling and resource management in forwarding POST requests.


81-98: Method correctly handles forwarding GET requests to an upstream server with proper error handling.


138-185: Method correctly handles different CoAP request types with appropriate error responses.


187-214: Method correctly handles GET requests with necessary authorization checks and error handling.


216-236: Ensure robust error handling and logging in handling POST requests.


238-291: Method correctly initializes the CoAP server based on configuration, with appropriate error handling and resource management.

README.md (5)

21-27: Architecture section clearly describes the flow of data through mProxy.


72-72: Deployment section accurately describes how mProxy is deployed alongside MQTT brokers.


Line range hint 90-126: Example setup and testing section provides comprehensive instructions for setting up and testing mProxy.


217-275: Configuration section accurately lists and describes the environment variables used for configuring mProxy.


Line range hint 281-306: Server and TLS configuration environment variables section provides detailed and clear information.

Comment on lines 14 to 15
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}\
-c $certfile -k $keyfile -C $cafile
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the command is split correctly over multiple lines.

- coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}\
+ coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}\
-c $certfile -k $keyfile -C $cafile
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \
-c $certfile -k $keyfile -C $cafile

Comment on lines 21 to 22
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}\
-c ssl/certs/client_unknown.crt -k ssl/certs/client_unknown.key -C $cafile
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the command is split correctly over multiple lines.

- coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}\
+ coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}\
-c ssl/certs/client_unknown.crt -k ssl/certs/client_unknown.key -C $cafile
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \
-c ssl/certs/client_unknown.crt -k ssl/certs/client_unknown.key -C $cafile

pkg/coap/coap.go Outdated
}, opts...)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error("cannot send error response: %v", err)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
p.logger.Error("cannot send error response: %v", err)
p.logger.Error("cannot send error response", slog.Attr("error", err))

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Out of diff range and nitpick comments (1)
README.md (1)

Line range hint 281-306: Consider removing the extra spaces before the colons in the list of environment variables for consistency.

- `ADDRESS` : Specifies the address at which mProxy will listen.
+ `ADDRESS`: Specifies the address at which mProxy will listen.
- `PATH_PREFIX` : Defines the path prefix when listening for MQTT over WebSocket or HTTP connections.
+ `PATH_PREFIX`: Defines the path prefix when listening for MQTT over WebSocket or HTTP connections.
- `TARGET` : Specifies the address of the target server, including any prefix path if available.
+ `TARGET`: Specifies the address of the target server, including any prefix path if available.
Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between db56b4b and 09b1ce7.
Files selected for processing (4)
  • README.md (10 hunks)
  • examples/client/coap/with_dtls.sh (1 hunks)
  • examples/client/coap/without_dtls.sh (1 hunks)
  • pkg/coap/coap.go (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • examples/client/coap/with_dtls.sh
  • examples/client/coap/without_dtls.sh
Additional Context Used
LanguageTool (20)
README.md (20)

Near line 26: Possible missing comma found.
Context: ...ts a new connection from a device. This way one device-mProxy connection correspond...


Near line 65: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...iven here, alongside with it's main() function. ...


Near line 65: Did you mean the possessive pronoun “its”?
Context: ...mples/simple/simple.go), alongside with it's main() function. ## D...


Near line 72: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...s a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node...


Near line 199: Use the singular noun “script” with the word ‘This’.
Context: ...ervers running for CoAP protocols. This scripts can be used after changing the `MPROXY_...


Near line 281: Loose punctuation mark.
Context: ...tion Environment Variables - ADDRESS : Specifies the address at which mProxy w...


Near line 282: Loose punctuation mark.
Context: ...HTTP proxy connections. - PATH_PREFIX : Defines the path prefix when listening ...


Near line 283: Loose punctuation mark.
Context: ...bSocket or HTTP connections. - TARGET : Specifies the address of the target ser...


Near line 287: Loose punctuation mark.
Context: ...on Environment Variables - CERT_FILE : Path to the TLS certificate file. - `KE...


Near line 288: Loose punctuation mark.
Context: ... the TLS certificate file. - KEY_FILE : Path to the TLS certificate key file. -...


Near line 289: Loose punctuation mark.
Context: ...ertificate key file. - SERVER_CA_FILE : Path to the Server CA certificate file....


Near line 290: Loose punctuation mark.
Context: ...CA certificate file. - CLIENT_CA_FILE : Path to the Client CA certificate file....


Near line 291: Loose punctuation mark.
Context: ...ate file. - CERT_VERIFICATION_METHODS : Methods for validating certificates. Ac...


Near line 297: Loose punctuation mark.
Context: ...n Environment Variables - OCSP_DEPTH : Depth of client certificate verificatio...


Near line 298: Loose punctuation mark.
Context: ...es are verified. - OCSP_RESPONDER_URL : Override value for the OCSP responder U...


Near line 302: Loose punctuation mark.
Context: ...ion Environment Variables - CRL_DEPTH: Depth of client certificate verificatio...


Near line 303: Loose punctuation mark.
Context: ...s verified. - CRL_DISTRIBUTION_POINTS : Override for the CRL Distribution Point...


Near line 304: Loose punctuation mark.
Context: ...L_DISTRIBUTION_POINTS_ISSUER_CERT_FILE` : Path to the issuer certificate file for...


Near line 305: Loose punctuation mark.
Context: ...TRIBUTION_POINTS. - OFFLINE_CRL_FILE` : Path to the offline CRL file, which can...


Near line 306: Loose punctuation mark.
Context: ...ction. - OFFLINE_CRL_ISSUER_CERT_FILE : Location of the issuer certificate file...

Additional comments not posted (3)
pkg/coap/coap.go (3)

36-42: LGTM! The NewProxy function correctly initializes the Proxy struct with the provided configuration, session handler, and logger.


44-52: LGTM! The sendErrorMessage function correctly constructs and sends an error message using the provided CoAP connection, token, error, and CoAP code.


124-124: Correct the logging format to include a key for the error attribute.

pkg/coap/coap.go Outdated
targetConn, err := udp.Dial(p.config.Target)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error("cannot send error response: %v", err)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
p.logger.Error("cannot send error response: %v", err)
p.logger.Error("cannot send error response", slog.Attr("error", err))

README.md Outdated
and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device,
in device-mProxy socket (OUTBOUND or DOWNLINK).
- The Device connects to mProxy's TCP server
- mProxy accepts the inbound (IN) connection and establishes a new session with the remote MQTT broker (i.e. it dials out to the MQTT broker only once it accepts a new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider revising the sentence for clarity and grammatical correctness.

- This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.
+ This way, each device-mProxy connection corresponds to one mProxy-MQTT broker connection.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
- mProxy accepts the inbound (IN) connection and establishes a new session with the remote MQTT broker (i.e. it dials out to the MQTT broker only once it accepts a new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
- mProxy accepts the inbound (IN) connection and establishes a new session with the remote MQTT broker (i.e. it dials out to the MQTT broker only once it accepts a new connection from a device. This way, each device-mProxy connection corresponds to one mProxy-MQTT broker connection.)

README.md Outdated
- Script to test mProxy server running at 5684 for CoAP with DTLS

```bash
examples/client/coap/without_dtls.sh
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the script path for testing the CoAP server with DTLS.

- examples/client/coap/without_dtls.sh
+ examples/client/coap/with_dtls.sh

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
examples/client/coap/without_dtls.sh
examples/client/coap/with_dtls.sh

README.md Outdated
@@ -77,11 +69,11 @@
mProxy does not do load balancing - just pure and simple proxying with TLS termination. This is why it should be deployed
right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).
Usually, this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

<p align="center"><img src="docs/img/mproxy-cluster.png"></p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding alternate text to the image for better accessibility.

- <p align="center"><img src="docs/img/mproxy-cluster.png"></p>
+ <p align="center"><img src="docs/img/mproxy-cluster.png" alt="mProxy cluster diagram"></p>

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
<p align="center"><img src="docs/img/mproxy-cluster.png"></p>
<p align="center"><img src="docs/img/mproxy-cluster.png" alt="mProxy cluster diagram"></p>

@felixgateru felixgateru force-pushed the mpx_24-coap branch 2 times, most recently from cced1d4 to fcc030d Compare May 10, 2024 07:34
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 09b1ce7 and fcc030d.
Files selected for processing (4)
  • README.md (10 hunks)
  • examples/client/coap/with_dtls.sh (1 hunks)
  • examples/client/coap/without_dtls.sh (1 hunks)
  • pkg/coap/coap.go (1 hunks)
Files not reviewed due to errors (1)
  • README.md (no review received)
Files skipped from review as they are similar to previous changes (2)
  • examples/client/coap/with_dtls.sh
  • examples/client/coap/without_dtls.sh
Additional Context Used
LanguageTool (19)
README.md (19)

Near line 65: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...iven here, alongside with it's main() function. ...


Near line 65: Did you mean the possessive pronoun “its”?
Context: ...mples/simple/simple.go), alongside with it's main() function. ## D...


Near line 72: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...s a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node...


Near line 199: Use the singular noun “script” with the word ‘This’.
Context: ...ervers running for CoAP protocols. This scripts can be used after changing the `MPROXY_...


Near line 281: Loose punctuation mark.
Context: ...tion Environment Variables - ADDRESS : Specifies the address at which mProxy w...


Near line 282: Loose punctuation mark.
Context: ...HTTP proxy connections. - PATH_PREFIX : Defines the path prefix when listening ...


Near line 283: Loose punctuation mark.
Context: ...bSocket or HTTP connections. - TARGET : Specifies the address of the target ser...


Near line 287: Loose punctuation mark.
Context: ...on Environment Variables - CERT_FILE : Path to the TLS certificate file. - `KE...


Near line 288: Loose punctuation mark.
Context: ... the TLS certificate file. - KEY_FILE : Path to the TLS certificate key file. -...


Near line 289: Loose punctuation mark.
Context: ...ertificate key file. - SERVER_CA_FILE : Path to the Server CA certificate file....


Near line 290: Loose punctuation mark.
Context: ...CA certificate file. - CLIENT_CA_FILE : Path to the Client CA certificate file....


Near line 291: Loose punctuation mark.
Context: ...ate file. - CERT_VERIFICATION_METHODS : Methods for validating certificates. Ac...


Near line 297: Loose punctuation mark.
Context: ...n Environment Variables - OCSP_DEPTH : Depth of client certificate verificatio...


Near line 298: Loose punctuation mark.
Context: ...es are verified. - OCSP_RESPONDER_URL : Override value for the OCSP responder U...


Near line 302: Loose punctuation mark.
Context: ...ion Environment Variables - CRL_DEPTH: Depth of client certificate verificatio...


Near line 303: Loose punctuation mark.
Context: ...s verified. - CRL_DISTRIBUTION_POINTS : Override for the CRL Distribution Point...


Near line 304: Loose punctuation mark.
Context: ...L_DISTRIBUTION_POINTS_ISSUER_CERT_FILE` : Path to the issuer certificate file for...


Near line 305: Loose punctuation mark.
Context: ...TRIBUTION_POINTS. - OFFLINE_CRL_FILE` : Path to the offline CRL file, which can...


Near line 306: Loose punctuation mark.
Context: ...ction. - OFFLINE_CRL_ISSUER_CERT_FILE : Location of the issuer certificate file...

Additional comments not posted (4)
pkg/coap/coap.go (4)

36-42: LGTM! The NewProxy function correctly initializes the Proxy struct.


54-79: LGTM! The postUpstream method correctly handles POST requests to the upstream server.


81-98: LGTM! The getUpstream method correctly handles GET requests to the upstream server.


238-291: LGTM! The Listen method correctly starts the CoAP server based on the configuration.

pkg/coap/coap.go Outdated
Comment on lines 44 to 78
func sendErrorMessage(cc mux.Conn, token []byte, err error, code codes.Code) error {
m := cc.AcquireMessage(cc.Context())
defer cc.ReleaseMessage(m)
m.SetCode(code)
m.SetBody(bytes.NewReader(([]byte)(err.Error())))
m.SetToken(token)
m.SetContentFormat(message.TextPlain)
return cc.WriteMessage(m)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func sendErrorMessage(cc mux.Conn, token []byte, err error, code codes.Code) error {
m := cc.AcquireMessage(cc.Context())
defer cc.ReleaseMessage(m)
m.SetCode(code)
m.SetBody(bytes.NewReader(([]byte)(err.Error())))
m.SetToken(token)
m.SetContentFormat(message.TextPlain)
return cc.WriteMessage(m)
}
func sendErrorMessage(cc mux.Conn, token []byte, err error, code codes.Code) error {
m := cc.AcquireMessage(cc.Context())
defer cc.ReleaseMessage(m)
m.SetCode(code)
m.SetBody(bytes.NewReader(([]byte)(err.Error())))
m.SetToken(token)
m.SetContentFormat(message.TextPlain)
return cc.WriteMessage(m)
}

pkg/coap/coap.go Outdated
Comment on lines 100 to 198
func (p *Proxy) observeUpstream(ctx context.Context, cc mux.Conn, opts []message.Option, token []byte, path string) {
targetConn, err := udp.Dial(p.config.Target)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(fmt.Sprintf("cannot send error response: %v", err))
}
}
defer targetConn.Close()
doneObserving := make(chan struct{})

obs, err := targetConn.Observe(ctx, path, func(req *pool.Message) {
req.SetToken(token)
if err := cc.WriteMessage(req); err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
p.logger.Error(err.Error())
}
if req.Code() == codes.NotFound {
close(doneObserving)
}
}, opts...)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(fmt.Sprintf("cannot send error response: %v", err))
}
}

select {
case <-doneObserving:
if err := obs.Cancel(ctx); err != nil {
p.logger.Error(fmt.Sprintf("failed to cancel observation:%v", err))
}
case <-ctx.Done():
return
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (p *Proxy) observeUpstream(ctx context.Context, cc mux.Conn, opts []message.Option, token []byte, path string) {
targetConn, err := udp.Dial(p.config.Target)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(fmt.Sprintf("cannot send error response: %v", err))
}
}
defer targetConn.Close()
doneObserving := make(chan struct{})
obs, err := targetConn.Observe(ctx, path, func(req *pool.Message) {
req.SetToken(token)
if err := cc.WriteMessage(req); err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
p.logger.Error(err.Error())
}
if req.Code() == codes.NotFound {
close(doneObserving)
}
}, opts...)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(fmt.Sprintf("cannot send error response: %v", err))
}
}
select {
case <-doneObserving:
if err := obs.Cancel(ctx); err != nil {
p.logger.Error(fmt.Sprintf("failed to cancel observation:%v", err))
}
case <-ctx.Done():
return
}
}
func (p *Proxy) observeUpstream(ctx context.Context, cc mux.Conn, opts []message.Option, token []byte, path string) {
targetConn, err := udp.Dial(p.config.Target)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
}
defer targetConn.Close()
doneObserving := make(chan struct{})
obs, err := targetConn.Observe(ctx, path, func(req *pool.Message) {
req.SetToken(token)
if err := cc.WriteMessage(req); err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
p.logger.Error(err.Error())
}
if req.Code() == codes.NotFound {
close(doneObserving)
}
}, opts...)
if err != nil {
if err := sendErrorMessage(cc, token, err, codes.BadGateway); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
}
select {
case <-doneObserving:
if err := obs.Cancel(ctx); err != nil {
p.logger.Error(fmt.Sprintf("failed to cancel observation:%v", err))
}
case <-ctx.Done():
return
}
}

pkg/coap/coap.go Outdated
Comment on lines 138 to 230
func (p *Proxy) handler(w mux.ResponseWriter, r *mux.Message) {
tok, err := r.Options().GetBytes(message.URIQuery)
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
ctx := session.NewContext(r.Context(), &session.Session{Password: tok})
if err := p.session.AuthConnect(ctx); err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
path, err := r.Options().Path()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadOption); err != nil {
p.logger.Error(err.Error())
}
return
}
switch r.Code() {
case codes.GET:
obs, err := r.Options().Observe()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadRequest); err != nil {
p.logger.Error(err.Error())
}
return
}
p.handleGet(ctx, path, w.Conn(), r.Token(), obs, r)

case codes.POST:
body, err := r.ReadBody()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadRequest); err != nil {
p.logger.Error(err.Error())
}
return
}
p.handlePost(ctx, w.Conn(), body, r.Token(), path, r)
default:
if err := sendErrorMessage(w.Conn(), r.Token(), errUnsupportedMethod, codes.MethodNotAllowed); err != nil {
p.logger.Error(err.Error())
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (p *Proxy) handler(w mux.ResponseWriter, r *mux.Message) {
tok, err := r.Options().GetBytes(message.URIQuery)
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
ctx := session.NewContext(r.Context(), &session.Session{Password: tok})
if err := p.session.AuthConnect(ctx); err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
path, err := r.Options().Path()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadOption); err != nil {
p.logger.Error(err.Error())
}
return
}
switch r.Code() {
case codes.GET:
obs, err := r.Options().Observe()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadRequest); err != nil {
p.logger.Error(err.Error())
}
return
}
p.handleGet(ctx, path, w.Conn(), r.Token(), obs, r)
case codes.POST:
body, err := r.ReadBody()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadRequest); err != nil {
p.logger.Error(err.Error())
}
return
}
p.handlePost(ctx, w.Conn(), body, r.Token(), path, r)
default:
if err := sendErrorMessage(w.Conn(), r.Token(), errUnsupportedMethod, codes.MethodNotAllowed); err != nil {
p.logger.Error(err.Error())
}
}
}
func (p *Proxy) handler(w mux.ResponseWriter, r *mux.Message) {
tok, err := r.Options().GetBytes(message.URIQuery)
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.Unauthorized); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
ctx := session.NewContext(r.Context(), &session.Session{Password: tok})
if err := p.session.AuthConnect(ctx); err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.Unauthorized); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
path, err := r.Options().Path()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadOption); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
switch r.Code() {
case codes.GET:
obs, err := r.Options().Observe()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadRequest); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
p.handleGet(ctx, path, w.Conn(), r.Token(), obs, r)
case codes.POST:
body, err := r.ReadBody()
if err != nil {
if err := sendErrorMessage(w.Conn(), r.Token(), err, codes.BadRequest); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
p.handlePost(ctx, w.Conn(), body, r.Token(), path, r)
default:
if err := sendErrorMessage(w.Conn(), r.Token(), errUnsupportedMethod, codes.MethodNotAllowed); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
}
}

pkg/coap/coap.go Outdated
Comment on lines 187 to 251
func (p *Proxy) handleGet(ctx context.Context, path string, con mux.Conn, token []byte, obs uint32, r *mux.Message) {
if err := p.session.AuthSubscribe(ctx, &[]string{path}); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
if err := p.session.Subscribe(ctx, &[]string{path}); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
switch {
// obs == 0, start observe
case obs == 0:
go p.observeUpstream(ctx, con, r.Options(), token, path)

default:
if err := p.getUpstream(con, r, token); err != nil {
p.logger.Error(fmt.Sprintf("error performing get: %v\n", err))
if err := sendErrorMessage(con, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
return
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (p *Proxy) handleGet(ctx context.Context, path string, con mux.Conn, token []byte, obs uint32, r *mux.Message) {
if err := p.session.AuthSubscribe(ctx, &[]string{path}); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
if err := p.session.Subscribe(ctx, &[]string{path}); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
switch {
// obs == 0, start observe
case obs == 0:
go p.observeUpstream(ctx, con, r.Options(), token, path)
default:
if err := p.getUpstream(con, r, token); err != nil {
p.logger.Error(fmt.Sprintf("error performing get: %v\n", err))
if err := sendErrorMessage(con, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
return
}
}
}
func (p *Proxy) handleGet(ctx context.Context, path string, con mux.Conn, token []byte, obs uint32, r *mux.Message) {
if err := p.session.AuthSubscribe(ctx, &[]string{path}); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
if err := p.session.Subscribe(ctx, &[]string{path}); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
switch {
// obs == 0, start observe
case obs == 0:
go p.observeUpstream(ctx, con, r.Options(), token, path)
default:
if err := p.getUpstream(con, r, token); err != nil {
p.logger.Error(fmt.Sprintf("error performing get: %v\n", err))
if err := sendErrorMessage(con, token, err, codes.BadGateway); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
}
}

pkg/coap/coap.go Outdated
Comment on lines 216 to 234
func (p *Proxy) handlePost(ctx context.Context, con mux.Conn, body, token []byte, path string, r *mux.Message) {
if err := p.session.AuthPublish(ctx, &path, &body); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
if err := p.session.Publish(ctx, &path, &body); err != nil {
if err := sendErrorMessage(con, token, err, codes.BadRequest); err != nil {
p.logger.Error(err.Error())
}
return
}
if err := p.postUpstream(con, r, token); err != nil {
p.logger.Debug(fmt.Sprintf("error performing post: %v\n", err))
if err := sendErrorMessage(con, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
return
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the logging format to include a key for the error attribute.

- p.logger.Error("cannot send error response: %v", err)
+ p.logger.Error("cannot send error response", slog.Attr("error", err))

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
func (p *Proxy) handlePost(ctx context.Context, con mux.Conn, body, token []byte, path string, r *mux.Message) {
if err := p.session.AuthPublish(ctx, &path, &body); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error(err.Error())
}
return
}
if err := p.session.Publish(ctx, &path, &body); err != nil {
if err := sendErrorMessage(con, token, err, codes.BadRequest); err != nil {
p.logger.Error(err.Error())
}
return
}
if err := p.postUpstream(con, r, token); err != nil {
p.logger.Debug(fmt.Sprintf("error performing post: %v\n", err))
if err := sendErrorMessage(con, token, err, codes.BadGateway); err != nil {
p.logger.Error(err.Error())
}
return
}
}
func (p *Proxy) handlePost(ctx context.Context, con mux.Conn, body, token []byte, path string, r *mux.Message) {
if err := p.session.AuthPublish(ctx, &path, &body); err != nil {
if err := sendErrorMessage(con, token, err, codes.Unauthorized); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
if err := p.session.Publish(ctx, &path, &body); err != nil {
if err := sendErrorMessage(con, token, err, codes.BadRequest); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
if err := p.postUpstream(con, r, token); err != nil {
p.logger.Debug(fmt.Sprintf("error performing post: %v\n", err))
if err := sendErrorMessage(con, token, err, codes.BadGateway); err != nil {
p.logger.Error("cannot send error response", slog.Attr("error", err))
}
return
}
}

@felixgateru felixgateru force-pushed the mpx_24-coap branch 2 times, most recently from d48c555 to 0089ebe Compare May 23, 2024 14:53
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range and nitpick comments (1)
README.md (1)

8-8: Clarify the purposes and capabilities of mProxy in the introduction to provide a better overview to new users.

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between fcc030d and d48c555.
Files ignored due to path filters (2)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum
Files selected for processing (11)
  • .env (2 hunks)
  • README.md (10 hunks)
  • cmd/main.go (9 hunks)
  • config.go (2 hunks)
  • examples/client/coap/with_dtls.sh (1 hunks)
  • examples/client/coap/without_dtls.sh (1 hunks)
  • examples/server/coap/main.go (1 hunks)
  • pkg/coap/coap.go (1 hunks)
  • pkg/mqtt/mqtt.go (1 hunks)
  • pkg/mqtt/websocket/websocket.go (3 hunks)
  • pkg/tls/tls.go (1 hunks)
Files skipped from review due to trivial changes (2)
  • examples/client/coap/with_dtls.sh
  • examples/client/coap/without_dtls.sh
Additional Context Used
LanguageTool (18)
README.md (18)

Near line 65: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...iven here, alongside with it's main() function. ...


Near line 65: Did you mean the possessive pronoun “its”?
Context: ...mples/simple/simple.go), alongside with it's main() function. ## D...


Near line 72: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...s a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node...


Near line 282: Loose punctuation mark.
Context: ...tion Environment Variables - ADDRESS : Specifies the address at which mProxy w...


Near line 283: Loose punctuation mark.
Context: ...HTTP proxy connections. - PATH_PREFIX : Defines the path prefix when listening ...


Near line 284: Loose punctuation mark.
Context: ...bSocket or HTTP connections. - TARGET : Specifies the address of the target ser...


Near line 288: Loose punctuation mark.
Context: ...on Environment Variables - CERT_FILE : Path to the TLS certificate file. - `KE...


Near line 289: Loose punctuation mark.
Context: ... the TLS certificate file. - KEY_FILE : Path to the TLS certificate key file. -...


Near line 290: Loose punctuation mark.
Context: ...ertificate key file. - SERVER_CA_FILE : Path to the Server CA certificate file....


Near line 291: Loose punctuation mark.
Context: ...CA certificate file. - CLIENT_CA_FILE : Path to the Client CA certificate file....


Near line 292: Loose punctuation mark.
Context: ...ate file. - CERT_VERIFICATION_METHODS : Methods for validating certificates. Ac...


Near line 298: Loose punctuation mark.
Context: ...n Environment Variables - OCSP_DEPTH : Depth of client certificate verificatio...


Near line 299: Loose punctuation mark.
Context: ...es are verified. - OCSP_RESPONDER_URL : Override value for the OCSP responder U...


Near line 303: Loose punctuation mark.
Context: ...ion Environment Variables - CRL_DEPTH: Depth of client certificate verificatio...


Near line 304: Loose punctuation mark.
Context: ...s verified. - CRL_DISTRIBUTION_POINTS : Override for the CRL Distribution Point...


Near line 305: Loose punctuation mark.
Context: ...L_DISTRIBUTION_POINTS_ISSUER_CERT_FILE` : Path to the issuer certificate file for...


Near line 306: Loose punctuation mark.
Context: ...TRIBUTION_POINTS. - OFFLINE_CRL_FILE` : Path to the offline CRL file, which can...


Near line 307: Loose punctuation mark.
Context: ...ction. - OFFLINE_CRL_ISSUER_CERT_FILE : Location of the issuer certificate file...

Markdownlint (2)
README.md (2)

29: null
Images should have alternate text (alt text)


74: null
Images should have alternate text (alt text)

Additional comments not posted (15)
pkg/mqtt/mqtt.go (1)

30-30: Standardize the constructor function for MQTT proxy.

The renaming of New to NewProxy aligns with the naming conventions used across other proxy functionalities in the project.

.env (1)

29-29: Ensure consistency in environment variable configurations.

The addition of PATH_PREFIX for different services is consistent and helps in better organizing the routes.

Also applies to: 39-39, 43-43, 50-50

pkg/mqtt/websocket/websocket.go (1)

31-31: Standardize the constructor function for WebSocket proxy.

The renaming of New to NewProxy aligns with the naming conventions used across other proxy functionalities in the project.

cmd/main.go (5)

16-16: Ensure the new imports are used appropriately in the code.


39-40: Introduction of CoAP constants for environment configuration is a good practice for maintainability.


69-69: Standardization of proxy creation functions to NewProxy enhances consistency across different protocols.

Also applies to: 81-81, 93-93, 105-105, 117-117, 129-129, 186-186, 198-198


180-201: Proper handling of errors during configuration loading and initialization of CoAP servers is crucial. Ensure that the error handling strategy is consistent across all proxy configurations.


21-21: Update to the latest version of the env package is noted. Verify that all environment variable usages are compatible with the new version.

pkg/coap/coap.go (4)

41-49: Refactor error handling to use structured logging.


136-183: Ensure that the error handling and logging are consistent and use structured logging where possible.


185-212: The error handling in the handleGet method should be consistent with other parts of the application. Consider using structured logging.


214-234: In the handlePost method, ensure that error handling is robust and follows the established patterns seen in other parts of the application.

README.md (3)

26-26: Grammar correction needed for clarity.


29-29: Add alternate text to images for better accessibility.

Also applies to: 74-74


126-127: Ensure consistency in protocol naming across the documentation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between fcc030d and 3c6d35e.
Files ignored due to path filters (2)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum
Files selected for processing (11)
  • .env (2 hunks)
  • README.md (10 hunks)
  • cmd/main.go (9 hunks)
  • config.go (2 hunks)
  • examples/client/coap/with_dtls.sh (1 hunks)
  • examples/client/coap/without_dtls.sh (1 hunks)
  • examples/server/coap/main.go (1 hunks)
  • pkg/coap/coap.go (1 hunks)
  • pkg/mqtt/mqtt.go (1 hunks)
  • pkg/mqtt/websocket/websocket.go (3 hunks)
  • pkg/tls/tls.go (1 hunks)
Files skipped from review due to trivial changes (2)
  • examples/client/coap/with_dtls.sh
  • examples/server/coap/main.go
Additional Context Used
LanguageTool (18)
README.md (18)

Near line 65: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...iven here, alongside with it's main() function. ...
Rule ID: ALONGSIDE_WITH


Near line 65: Did you mean the possessive pronoun “its”?
Context: ...mples/simple/simple.go), alongside with it's main() function. ## D...
Rule ID: IT_S_ITS


Near line 72: This phrase is redundant. Consider writing “alongside” or “with”.
Context: ...s a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node...
Rule ID: ALONGSIDE_WITH


Near line 282: Loose punctuation mark.
Context: ...tion Environment Variables - ADDRESS : Specifies the address at which mProxy w...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 283: Loose punctuation mark.
Context: ...HTTP proxy connections. - PATH_PREFIX : Defines the path prefix when listening ...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 284: Loose punctuation mark.
Context: ...bSocket or HTTP connections. - TARGET : Specifies the address of the target ser...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 288: Loose punctuation mark.
Context: ...on Environment Variables - CERT_FILE : Path to the TLS certificate file. - `KE...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 289: Loose punctuation mark.
Context: ... the TLS certificate file. - KEY_FILE : Path to the TLS certificate key file. -...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 290: Loose punctuation mark.
Context: ...ertificate key file. - SERVER_CA_FILE : Path to the Server CA certificate file....
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 291: Loose punctuation mark.
Context: ...CA certificate file. - CLIENT_CA_FILE : Path to the Client CA certificate file....
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 292: Loose punctuation mark.
Context: ...ate file. - CERT_VERIFICATION_METHODS : Methods for validating certificates. Ac...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 298: Loose punctuation mark.
Context: ...n Environment Variables - OCSP_DEPTH : Depth of client certificate verificatio...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 299: Loose punctuation mark.
Context: ...es are verified. - OCSP_RESPONDER_URL : Override value for the OCSP responder U...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 303: Loose punctuation mark.
Context: ...ion Environment Variables - CRL_DEPTH: Depth of client certificate verificatio...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 304: Loose punctuation mark.
Context: ...s verified. - CRL_DISTRIBUTION_POINTS : Override for the CRL Distribution Point...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 305: Loose punctuation mark.
Context: ...L_DISTRIBUTION_POINTS_ISSUER_CERT_FILE` : Path to the issuer certificate file for...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 306: Loose punctuation mark.
Context: ...TRIBUTION_POINTS. - OFFLINE_CRL_FILE` : Path to the offline CRL file, which can...
Rule ID: UNLIKELY_OPENING_PUNCTUATION


Near line 307: Loose punctuation mark.
Context: ...ction. - OFFLINE_CRL_ISSUER_CERT_FILE : Location of the issuer certificate file...
Rule ID: UNLIKELY_OPENING_PUNCTUATION

Markdownlint (2)
README.md (2)

29: null
Images should have alternate text (alt text)


74: null
Images should have alternate text (alt text)

Additional comments not posted (14)
pkg/mqtt/mqtt.go (1)

30-30: Rename function to NewProxy to clarify its purpose.

This change aligns with best practices for naming in Go, making the function's purpose more explicit.

.env (1)

29-29: Update path and address configurations to reflect new standards.

These changes ensure consistency and clarity in environment variable naming and usage.

Also applies to: 39-39, 43-43, 50-50, 59-59, 62-62

pkg/mqtt/websocket/websocket.go (1)

32-32: Rename function to NewProxy to clarify its purpose.

This change improves clarity and consistency in the codebase.

pkg/tls/tls.go (1)

30-30: Implement generic type constraints for TLS and DTLS configurations.

This change introduces a flexible and type-safe way to handle different security configurations.

cmd/main.go (3)

69-69: The instantiation of various proxies (mqttProxy, mqttTLSProxy, mqttMTlsProxy, wsProxy, wsTLSProxy, wsMTLSProxy, coapProxy, coapDTLSProxy) using the NewProxy method is consistent. Ensure that the NewProxy method handles the configurations correctly, especially with the new CoAP support.

Also applies to: 81-81, 93-93, 105-105, 117-117, 129-129, 186-189, 198-201


21-21: Update to github.com/caarlos0/env/v11 is noted. Ensure all dependent configurations are compatible with this version.

Verification successful

The extracted code snippets show that the env package is used primarily for parsing environment variables into configuration structs using the env.ParseWithOptions method. This usage pattern is consistent across multiple files.

To ensure compatibility with version 11 of the env package, I reviewed the documentation for github.com/caarlos0/env and found no breaking changes or new features in version 11 that would affect the current usage patterns in the codebase.

Therefore, the update to github.com/caarlos0/env/v11 appears to be compatible with the existing configurations.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify compatibility of `env` package version 11 with existing configurations.

# Test: Search for the usage of `env` package. Expect: Proper handling of new features or breaking changes in version 11.
rg --type go $'github.com/caarlos0/env/v11'

Length of output: 351



Script:

#!/bin/bash
# Description: Extract and review the usage of the `env` package in the identified files to ensure compatibility with version 11.

# Extract usage of `env` package in config.go
echo "config.go:"
rg --type go --context 5 'env' config.go

# Extract usage of `env` package in pkg/tls/verifications.go
echo "pkg/tls/verifications.go:"
rg --type go --context 5 'env' pkg/tls/verifications.go

# Extract usage of `env` package in pkg/tls/config.go
echo "pkg/tls/config.go:"
rg --type go --context 5 'env' pkg/tls/config.go

# Extract usage of `env` package in pkg/tls/verifier/ocsp/ocsp.go
echo "pkg/tls/verifier/ocsp/ocsp.go:"
rg --type go --context 5 'env' pkg/tls/verifier/ocsp/ocsp.go

# Extract usage of `env` package in pkg/tls/verifier/crl/crl.go
echo "pkg/tls/verifier/crl/crl.go:"
rg --type go --context 5 'env' pkg/tls/verifier/crl/crl.go

# Extract usage of `env` package in cmd/main.go
echo "cmd/main.go:"
rg --type go --context 5 'env' cmd/main.go

Length of output: 10143


39-40: New constants for CoAP configurations (coapWithoutDTLS and coapWithDTLS) are added and used in the configuration setup for CoAP servers. Ensure these constants are correctly defined and used throughout the codebase.

Also applies to: 179-201

pkg/coap/coap.go (4)

29-29: Definition of errUnsupportedMethod for handling unsupported CoAP methods is a good practice for clarity and maintainability.


61-67: Creation of the Proxy struct with configuration, session handler, and logger is well-structured. Ensure that all fields are utilized effectively within the proxy methods.


69-77: The function sendErrorMessage is used to handle error responses consistently across CoAP operations. Ensure that the error logging within this function adheres to the structured logging format as previously noted.


79-105: The methods for handling CoAP requests (postUpstream, getUpstream, observeUpstream, CancelObservation, handler, handleGet, handlePost, Listen) are comprehensive and cover various scenarios. Ensure that all error handling and resource management patterns are consistent and robust, particularly with network connections and message handling.

Also applies to: 107-124, 126-176, 178-205, 207-247, 249-292, 294-314, 316-371

README.md (3)

8-8: The description of mProxy's deployment and usage is clear. Ensure that all features mentioned are documented in detail in the corresponding sections.


115-127: The setup instructions for various mProxy servers are clear and detailed. Ensure that all script paths and commands are correct and up-to-date.


197-212: Scripts for testing CoAP protocols are mentioned. Verify that these scripts are available and functional as described.

Verification successful

The CoAP testing scripts examples/client/coap/without_dtls.sh and examples/client/coap/with_dtls.sh are available and executable. Their contents indicate they are correctly implemented to test CoAP protocols with and without DTLS.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the availability and functionality of CoAP testing scripts.

# Test: Check for the existence and execution of CoAP testing scripts.
ls examples/client/coap/without_dtls.sh
ls examples/client/coap/with_dtls.sh

Length of output: 151



Script:

#!/bin/bash
# Description: Verify the functionality of CoAP testing scripts.

# Test: Display the contents of the CoAP testing scripts.
cat examples/client/coap/without_dtls.sh
cat examples/client/coap/with_dtls.sh

# Test: Check if the scripts are executable.
test -x examples/client/coap/without_dtls.sh && echo "without_dtls.sh is executable" || echo "without_dtls.sh is not executable"
test -x examples/client/coap/with_dtls.sh && echo "with_dtls.sh is executable" || echo "with_dtls.sh is not executable"

Length of output: 2367


#Examples using Magisrala coap-cli
echo "Posting message to ${protocol}://${host}:${port}/${path} without tls ..."
coap-cli post ${host}:${port}/${path} -d "${message}" -O 12,${content} -O 15,auth=${auth}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The script examples/client/coap/without_dtls.sh lacks error handling for coap-cli commands. Consider adding error handling to ensure robustness.

  • File: examples/client/coap/without_dtls.sh
  • Lines: 19, 23
Analysis chain

Consider adding error handling for coap-cli commands to ensure robustness.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify error handling for coap-cli commands.

# Test: Search for error handling patterns in coap-cli usage.
rg --type sh $'coap-cli.*|| echo'

Length of output: 18922

@@ -13,11 +13,12 @@ import (

"github.com/absmach/mproxy"
"github.com/absmach/mproxy/examples/simple"
"github.com/absmach/mproxy/pkg/coap"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The newly imported coap package (github.com/absmach/mproxy/pkg/coap) is not utilized anywhere in the codebase. Please ensure that this import is either used appropriately in the code or removed if it is not needed.

  • Unused import found in cmd/main.go at line 16.
Analysis chain

Ensure the new import github.com/absmach/mproxy/pkg/coap is utilized properly in the code.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the usage of the newly imported `coap` package.

# Test: Search for the usage of the `coap` package. Expect: At least one usage in the file.
ast-grep --lang go --pattern $'import "github.com/absmach/mproxy/pkg/coap" { $$$ }'

Length of output: 558



Script:

#!/bin/bash
# Description: Verify the usage of the newly imported `coap` package.

# Test: Search for the usage of the `coap` package. Expect: At least one usage in the codebase.
ast-grep --lang go --pattern $'coap.$_' --json

Length of output: 50


#Examples using lib-coap coap-client
echo "Posting message to ${protocol}://${host}:${port}/${path} without tls ..."
coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Ensure proper error handling for the coap-client command in the examples/client/coap/without_dtls.sh script. The current implementation does not handle errors, which could lead to unhandled failures.

  • File: examples/client/coap/without_dtls.sh
  • Lines: 12

Consider adding error handling like this:

coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} || { echo "Failed to post message"; exit 1; }
Analysis chain

Ensure proper error handling for the coap-client command.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Check if error handling is implemented for coap-client commands.

# Test: Search for error handling patterns in coap-client usage.
rg --type sh $'coap-client.*|| echo'

Length of output: 18925

@@ -27,8 +29,11 @@ func NewConfig(opts env.Options) (Config, error) {
if err != nil {
return Config{}, err
}

c.TLSConfig, err = mptls.Load(&cfg)
c.TLSConfig, err = mptls.LoadTLSConfig(&cfg, &tls.Config{})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set the minimum TLS version to TLS 1.3 to enhance security.

- c.TLSConfig, err = mptls.LoadTLSConfig(&cfg, &tls.Config{})
+ c.TLSConfig, err = mptls.LoadTLSConfig(&cfg, &tls.Config{MinVersion: tls.VersionTLS13})

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
c.TLSConfig, err = mptls.LoadTLSConfig(&cfg, &tls.Config{})
c.TLSConfig, err = mptls.LoadTLSConfig(&cfg, &tls.Config{MinVersion: tls.VersionTLS13})

@@ -57,7 +50,7 @@ var upgrader = websocket.Upgrader{
}

func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != p.config.PrefixPath {
if !strings.HasPrefix(r.URL.Path, p.config.PathPrefix) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the path prefix check is case-insensitive for better robustness.

- if !strings.HasPrefix(r.URL.Path, p.config.PathPrefix) {
+ if !strings.HasPrefix(strings.ToLower(r.URL.Path), strings.ToLower(p.config.PathPrefix)) {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
if !strings.HasPrefix(r.URL.Path, p.config.PathPrefix) {
if !strings.HasPrefix(strings.ToLower(r.URL.Path), strings.ToLower(p.config.PathPrefix)) {

README.md Outdated
in device-mProxy socket (OUTBOUND or DOWNLINK).
- The Device connects to mProxy's TCP server
- mProxy accepts the inbound (IN) connection and establishes a new session with the remote MQTT broker (i.e. it dials out to the MQTT broker only once it accepts a new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
- mProxy then spawns 2 goroutines: one that will read incoming packets from the device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

<p align="center"><img src="docs/img/mproxy.png"></p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Images in the README should have alternate text for better accessibility.

- <p align="center"><img src="docs/img/mproxy.png"></p>
+ <p align="center"><img src="docs/img/mproxy.png" alt="mProxy architecture diagram"></p>
- <p align="center"><img src="docs/img/mproxy-cluster.png"></p>
+ <p align="center"><img src="docs/img/mproxy-cluster.png" alt="mProxy cluster diagram"></p>

Also applies to: 74-74

Committable suggestion was skipped due low confidence.

README.md Outdated
```

## Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker.
It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.
mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to the MQTT broker, inspecting or modifying them as they flow through the proxy.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The architecture description provides a good overview of mProxy's functionality. Consider adding more diagrams or flowcharts for better visual understanding.

+ Consider adding more diagrams or flowcharts to enhance the visual understanding of mProxy's architecture.

Committable suggestion was skipped due low confidence.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 3c6d35e and 7c46c68.

Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
Files selected for processing (3)
  • go.mod (1 hunks)
  • pkg/coap/coap.go (1 hunks)
  • pkg/tls/tls.go (2 hunks)
Additional comments not posted (27)
go.mod (12)

13-13: Dependency github.com/pion/dtls/v2 looks good.

The addition of this dependency is likely to support DTLS functionality.


14-14: Dependency github.com/plgd-dev/go-coap/v3 looks good.

The addition of this dependency is likely to support CoAP functionality.


20-20: Indirect dependency github.com/dsnet/golib/memfile looks good.

The addition of this dependency is likely required by another dependency.


21-21: Dependency github.com/dustin/go-coap looks good.

The addition of this dependency is likely to support CoAP functionality.


22-22: Indirect dependency github.com/hashicorp/errwrap looks good.

The addition of this dependency is likely required by another dependency.


23-23: Indirect dependency github.com/hashicorp/go-multierror looks good.

The addition of this dependency is likely required by another dependency.


24-24: Indirect dependency github.com/pion/logging looks good.

The addition of this dependency is likely required by another dependency.


25-25: Indirect dependency github.com/pion/transport/v3 looks good.

The addition of this dependency is likely required by another dependency.


26-26: Indirect dependency go.uber.org/atomic looks good.

The addition of this dependency is likely required by another dependency.


27-27: Indirect dependency golang.org/x/exp looks good.

The addition of this dependency is likely required by another dependency.


28-28: Indirect dependency golang.org/x/net looks good.

The addition of this dependency is likely required by another dependency.


29-29: Indirect dependency golang.org/x/sys looks good.

The addition of this dependency is likely required by another dependency.

pkg/tls/tls.go (7)

13-13: Import github.com/pion/dtls/v2 looks good.

The addition of this import is necessary to support DTLS functionality.


17-22: Error variables look good.

The addition of these error variables improves error handling and clarity.


25-27: TLSConfig interface looks good.

The addition of this interface is necessary for the generic LoadTLSConfig function to handle both TLS and DTLS configurations.


29-106: LoadTLSConfig function looks good.

The addition of this function is necessary for loading TLS and DTLS configurations based on the provided type. The function includes appropriate error handling.


108-127: SecurityStatus function looks good.

The modification of this function is necessary to return status messages for both TLS and DTLS configurations.


Line range hint 129-144:
ClientCert function looks good.

The addition of this function is necessary for retrieving the client certificate from a TLS connection.


Line range hint 146-151:
loadCertFile function looks good.

The addition of this function is necessary for loading certificate files for TLS and DTLS configurations.

pkg/coap/coap.go (8)

6-20: Import statements look good.

The addition of these imports is necessary to support CoAP and DTLS functionality.


24-27: Global variables ConnMap and mutex look good.

The addition of these variables is necessary for managing connections and ensuring thread safety.


29-32: Conn struct looks good.

The addition of this struct is necessary for managing client and server connections.


34-38: Proxy struct looks good.

The addition of this struct is necessary for managing the CoAP proxy configuration, session handler, and logger.


40-46: NewProxy function looks good.

The addition of this function is necessary for initializing a new Proxy instance with the provided configuration, session handler, and logger.


48-75: proxy function looks good.

The addition of this function is necessary for managing the proxying of UDP connections and handling new connections.


77-129: Listen function looks good.

The addition of this function is necessary for initializing the CoAP proxy server and handling DTLS and UDP connections.


131-144: newConn function looks good.

The addition of this function is necessary for initializing a new connection with the client and server addresses.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7c46c68 and bbfe721.

Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
Files selected for processing (3)
  • go.mod (1 hunks)
  • pkg/coap/coap.go (1 hunks)
  • pkg/tls/tls.go (2 hunks)
Files skipped from review due to trivial changes (1)
  • pkg/coap/coap.go
Additional comments not posted (16)
go.mod (12)

13-13: Approved: Addition of DTLS library.

The addition of github.com/pion/dtls/v2 aligns with the PR objective of adding DTLS support.


14-14: Approved: Addition of CoAP library.

The addition of github.com/plgd-dev/go-coap/v3 aligns with the PR objective of adding CoAP support.


20-20: Approved: Addition of indirect dependency.

The addition of github.com/dsnet/golib/memfile as an indirect dependency is acceptable.


21-21: Approved: Addition of another CoAP library.

The addition of github.com/dustin/go-coap aligns with the PR objective of adding CoAP support.


22-22: Approved: Addition of indirect dependency.

The addition of github.com/hashicorp/errwrap as an indirect dependency is acceptable.


23-23: Approved: Addition of indirect dependency.

The addition of github.com/hashicorp/go-multierror as an indirect dependency is acceptable.


24-24: Approved: Addition of indirect dependency.

The addition of github.com/pion/logging as an indirect dependency is acceptable.


25-25: Approved: Addition of indirect dependency.

The addition of github.com/pion/transport/v3 as an indirect dependency is acceptable.


26-26: Approved: Addition of indirect dependency.

The addition of go.uber.org/atomic as an indirect dependency is acceptable.


27-27: Approved: Addition of indirect dependency.

The addition of golang.org/x/exp as an indirect dependency is acceptable.


28-28: Approved: Addition of indirect dependency.

The addition of golang.org/x/net as an indirect dependency is acceptable.


29-29: Approved: Addition of indirect dependency.

The addition of golang.org/x/sys as an indirect dependency is acceptable.

pkg/tls/tls.go (4)

13-13: Approved: Addition of DTLS import.

The addition of github.com/pion/dtls/v2 aligns with the PR objective of adding DTLS support.


25-27: Approved: Introduction of TLSConfig interface.

The introduction of the TLSConfig interface to handle both *tls.Config and *dtls.Config enhances flexibility and modularity.


29-106: Approved: Introduction of LoadTLSConfig function.

The introduction of the LoadTLSConfig function to handle both TLS and DTLS configurations is well-implemented. Ensure MinVersion is set for both configurations to enforce secure protocol versions.
[approved, verify]

#!/bin/bash
# Description: Verify that MinVersion is set in the TLS and DTLS configurations.

# Test: Search for MinVersion in the tls.go file. Expect: MinVersion is set for both TLS and DTLS.
rg --type go 'MinVersion' pkg/tls/tls.go

108-127: Approved: Modification of SecurityStatus function.

The modification of the SecurityStatus function to handle both TLS and DTLS configurations is well-implemented and reduces redundancy.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range, codebase verification and nitpick comments (12)
config.go (1)

32-36: Ensure DTLS Configuration is Handled in All Proxies

The DTLSConfig is currently utilized only within the pkg/coap package. Other proxy implementations (pkg/websockets, pkg/mqtt, pkg/mqtt/websocket, pkg/http) do not handle the DTLSConfig.

  • pkg/websockets
  • pkg/mqtt
  • pkg/mqtt/websocket
  • pkg/http

These packages need to be updated to handle the DTLSConfig similarly to how it is handled in pkg/coap.

Analysis chain

LGTM! But verify the function usage in the codebase.

The changes to the NewConfig function are approved.

However, ensure that all calls to NewConfig are updated to handle the new DTLS configuration.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `NewConfig` in the codebase.

# Test: Search for the function usage. Expect: Only occurrences of the updated function.
rg --type go -A 5 $'NewConfig'

Length of output: 3207


Script:

#!/bin/bash
# Description: Verify the usage of the `Config` object returned by `NewConfig` to ensure DTLS configuration is handled.

# Search for the usage of the `Config` object in the identified files.
rg --type go -A 10 'NewConfig' config.go pkg/tls/config.go cmd/main.go

Length of output: 5709


Script:

#!/bin/bash
# Description: Verify the handling of `DTLSConfig` in proxy constructors.

# Search for the implementations of the proxy constructors to ensure DTLS configuration is handled.
rg --type go 'func NewProxy' -A 10

Length of output: 2928


Script:

#!/bin/bash
# Description: Verify the usage of `DTLSConfig` within the proxy implementations.

# Search for the usage of `DTLSConfig` in the proxy implementations.
rg --type go 'DTLSConfig' pkg/coap pkg/websockets pkg/mqtt pkg/mqtt/websocket pkg/http

Length of output: 282

cmd/main.go (11)

38-40: Add comments for new constants.

Add comments to explain the purpose of the new constants coapWithoutDTLS and coapWithDTLS for better readability and maintainability.

const (
	// CoAP server configuration without DTLS
	coapWithoutDTLS = "MPROXY_COAP_WITHOUT_DTLS_"
	// CoAP server configuration with DTLS
	coapWithDTLS    = "MPROXY_COAP_WITH_DTLS_"
)

69-69: Update the comment to reflect the new function name.

The function mqtt.New has been renamed to mqtt.NewProxy. Update the comment accordingly.

- // mProxy server for MQTT without TLS
+ // mProxy server for MQTT without TLS using NewProxy

81-81: Update the comment to reflect the new function name.

The function mqtt.New has been renamed to mqtt.NewProxy. Update the comment accordingly.

- // mProxy server for MQTT with TLS
+ // mProxy server for MQTT with TLS using NewProxy

93-93: Update the comment to reflect the new function name.

The function mqtt.New has been renamed to mqtt.NewProxy. Update the comment accordingly.

- // mProxy server for MQTT with mTLS
+ // mProxy server for MQTT with mTLS using NewProxy

105-105: Update the comment to reflect the new function name.

The function websocket.New has been renamed to websocket.NewProxy. Update the comment accordingly.

- // mProxy server for MQTT over Websocket without TLS
+ // mProxy server for MQTT over Websocket without TLS using NewProxy

117-117: Update the comment to reflect the new function name.

The function websocket.New has been renamed to websocket.NewProxy. Update the comment accordingly.

- // mProxy server for MQTT over Websocket with TLS
+ // mProxy server for MQTT over Websocket with TLS using NewProxy

129-129: Update the comment to reflect the new function name.

The function websocket.New has been renamed to websocket.NewProxy. Update the comment accordingly.

- // mProxy server for MQTT over Websocket with mTLS
+ // mProxy server for MQTT over Websocket with mTLS using NewProxy

179-183: Add comments for CoAP configuration.

Add comments to explain the purpose of the CoAP configuration for better readability and maintainability.

// mProxy server Configuration for CoAP without DTLS
coapConfig, err := mproxy.NewConfig(env.Options{Prefix: coapWithoutDTLS})
if err != nil {
	panic(err)
}

185-189: Add comments for CoAP proxy initialization.

Add comments to explain the purpose of the CoAP proxy initialization for better readability and maintainability.

// mProxy server for CoAP without DTLS
coapProxy := coap.NewProxy(coapConfig, handler, logger)
g.Go(func() error {
	return coapProxy.Listen(ctx)
})

191-195: Add comments for CoAP configuration.

Add comments to explain the purpose of the CoAP configuration for better readability and maintainability.

// mProxy server Configuration for CoAP with DTLS
coapDTLSConfig, err := mproxy.NewConfig(env.Options{Prefix: coapWithDTLS})
if err != nil {
	panic(err)
}

197-201: Add comments for CoAP proxy initialization.

Add comments to explain the purpose of the CoAP proxy initialization for better readability and maintainability.

// mProxy server for CoAP with DTLS
coapDTLSProxy := coap.NewProxy(coapDTLSConfig, handler, logger)
g.Go(func() error {
	return coapDTLSProxy.Listen(ctx)
})
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between bbfe721 and 6dac25c.

Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
Files selected for processing (13)
  • .env (1 hunks)
  • README.md (4 hunks)
  • cmd/main.go (9 hunks)
  • config.go (2 hunks)
  • examples/client/coap/with_dtls.sh (1 hunks)
  • examples/client/coap/without_dtls.sh (1 hunks)
  • examples/server/coap/main.go (1 hunks)
  • go.mod (1 hunks)
  • pkg/coap/coap.go (1 hunks)
  • pkg/mqtt/mqtt.go (1 hunks)
  • pkg/mqtt/websocket/websocket.go (1 hunks)
  • pkg/session/stream.go (1 hunks)
  • pkg/tls/tls.go (2 hunks)
Files skipped from review due to trivial changes (3)
  • examples/client/coap/without_dtls.sh
  • pkg/mqtt/mqtt.go
  • pkg/mqtt/websocket/websocket.go
Files skipped from review as they are similar to previous changes (2)
  • pkg/coap/coap.go
  • pkg/tls/tls.go
Additional comments not posted (19)
config.go (2)

11-11: LGTM!

The dtls package is correctly imported to support DTLS configuration.


16-19: LGTM! But verify the usage of PathPrefix and DTLSConfig in the codebase.

The changes to PathPrefix and the addition of DTLSConfig are approved.

However, ensure that all usages of PathPrefix and DTLSConfig in the codebase are updated accordingly.

Verification successful

LGTM! The usages of PathPrefix and DTLSConfig have been verified.

The changes to PathPrefix and the addition of DTLSConfig are correctly reflected and used in the codebase.

  • PathPrefix is used in pkg/mqtt/websocket/websocket.go and pkg/http/http.go.
  • DTLSConfig is used in pkg/coap/coap.go and cmd/main.go.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `PathPrefix` and `DTLSConfig` in the codebase.

# Test: Search for the usage of `PathPrefix`. Expect: Only occurrences of the new default value.
rg --type go -A 5 $'PathPrefix'

# Test: Search for the usage of `DTLSConfig`. Expect: Only occurrences of the new field.
rg --type go -A 5 $'DTLSConfig'

Length of output: 4580

go.mod (3)

9-9: LGTM!

The github.com/dustin/go-coap package is correctly added to support CoAP functionality.


14-15: LGTM!

The github.com/pion/dtls/v2 and github.com/plgd-dev/go-coap/v3 packages are correctly added to support DTLS and CoAP functionality.


21-29: LGTM!

The indirect dependencies are correctly added as required by the new direct dependencies.

examples/server/coap/main.go (4)

1-15: LGTM!

The package declaration and imports are correctly set up for the CoAP server.


17-17: LGTM!

The defaultPort constant is correctly set up for the CoAP server.


19-30: LGTM!

The handleRequest function is correctly implemented to handle incoming CoAP requests and send appropriate responses.


32-37: LGTM!

The main function is correctly implemented to start the CoAP server.

examples/client/coap/with_dtls.sh (3)

21-22: Ensure the command is split correctly over multiple lines.

There should be a space before the backslash to ensure the command is split correctly.

- coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \
+ coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \

Likely invalid or redundant comment.


14-15: Ensure the command is split correctly over multiple lines.

There should be a space before the backslash to ensure the command is split correctly.

- coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \
+ coap-client -m post coap://${host}:${port}/${path} -e "${message}" -O 12,${content} -O 15,auth=${auth} \

Likely invalid or redundant comment.


25-25: Ensure the command is split correctly over multiple lines.

There should be a space before the backslash to ensure the command is split correctly.

- coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c ssl/certs/client_unknown.crt -k ssl/certs/client_unknown.key -C $cafile
+ coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c ssl/certs/client_unknown.crt -k ssl/certs/client_unknown.key -C $cafile \

Likely invalid or redundant comment.

.env (1)

59-68: Ensure consistency in variable naming and usage.

The new CoAP variables are consistent with existing MQTT variables. Ensure that the paths to certificate files are correct and accessible.

pkg/session/stream.go (1)

61-75: Ensure robust error handling and authorization logic.

The new switch statement enhances the control flow and introduces additional authorization checks. Ensure that all potential errors are handled correctly and that the authorization logic is robust.

cmd/main.go (1)

16-16: Ensure the coap package is utilized.

The coap package is imported but not utilized anywhere in the codebase.

README.md (4)

85-85: Ensure consistent capitalization for protocol names.

Ensure that the protocol name CoAP is consistently capitalized throughout the document.


126-127: Ensure consistent capitalization for protocol names.

Ensure that the protocol name CoAP is consistently capitalized throughout the document.


197-213: Ensure consistent capitalization for protocol names.

Ensure that the protocol name CoAP is consistently capitalized throughout the document.


269-276: Ensure consistent capitalization for protocol names.

Ensure that the protocol name CoAP is consistently capitalized throughout the document.

Comment on lines +1 to +11
#!/bin/bash
protocol=coaps
host=localhost
port=5684
path="test"
content=0x32
message="{\"message\": \"Hello mProxy\"}"
auth="TOKEN"
cafile=ssl/certs/ca.crt
certfile=ssl/certs/client.crt
keyfile=ssl/certs/client.key
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure secure handling of sensitive data.

The auth variable contains a token that should be securely managed. Consider using environment variables or a secure vault for sensitive data.

-c $certfile -k $keyfile -C $cafile

echo "Getting message from ${protocol}://${host}:${port}/${path} with dtls ..."
coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c $certfile -k $keyfile -C $cafile
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure the command is split correctly over multiple lines.

There should be a space before the backslash to ensure the command is split correctly.

- coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c $certfile -k $keyfile -C $cafile
+ coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c $certfile -k $keyfile -C $cafile \
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c $certfile -k $keyfile -C $cafile
coap-client -m get coap://${host}:${port}/${path} -O 6,0x00 -O 15,auth=${auth} -c $certfile -k $keyfile -C $cafile \

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6dac25c and 0f62fe0.

Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
Files selected for processing (3)
  • go.mod (1 hunks)
  • pkg/coap/coap.go (1 hunks)
  • pkg/tls/tls.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • go.mod
Additional comments not posted (13)
pkg/tls/tls.go (5)

12-13: Import statement for DTLS is necessary.

The addition of github.com/pion/dtls/v2 is required to support DTLS configuration.


17-22: Error handling improvements.

The addition of specific error variables enhances error handling and code readability.


25-27: Introduction of TLSConfig interface.

The new TLSConfig interface enhances flexibility and reusability by supporting both *tls.Config and *dtls.Config.


108-127: Update to SecurityStatus function.

The update to handle both TLS and DTLS configurations is necessary and improves code consistency.


Line range hint 135-147:
Loading certificate files.

The loadCertFile function is straightforward and necessary for loading certificates.

pkg/coap/coap.go (8)

1-20: Introduction of CoAP package and import statements.

The package coap and the import statements are necessary for the implementation of the CoAP proxy server.


22-30: Introduction of constants and variables.

The constants and variables are necessary for the CoAP proxy server's functionality.


32-41: Introduction of Conn and Proxy structs.

The Conn and Proxy structs are essential for organizing the CoAP proxy server's components.


43-49: Initialization of a new Proxy instance.

The NewProxy function is necessary for creating and configuring a new CoAP proxy server.


51-78: Handling UDP proxying.

The proxyUDP function is essential for managing UDP connections and data transfer.


80-131: Starting the CoAP proxy server.

The Listen function is crucial for starting and managing the CoAP proxy server, handling both UDP and DTLS connections.


134-174: Managing connections and data transfer.

The newConn, upUDP, and downUDP functions are necessary for managing new connections and handling data transfer in the CoAP proxy server.


183-288: Handling DTLS connections and CoAP messages.

The functions for handling DTLS connections and CoAP messages are essential for supporting DTLS and processing CoAP messages in the proxy server.

Comment on lines +29 to +106
// LoadTLSConfig returns a TLS or DTLS configuration that can be used for TLS or DTLS servers.
func LoadTLSConfig[sc TLSConfig](c *Config, s sc) (sc, error) {
if c.CertFile == "" || c.KeyFile == "" {
return nil, nil
}

tlsConfig := &tls.Config{}

certificate, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
if err != nil {
return nil, errors.Join(errLoadCerts, err)
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{certificate},
}

// Loading Server CA file
rootCA, err := loadCertFile(c.ServerCAFile)
if err != nil {
return nil, errors.Join(errLoadServerCA, err)
}
if len(rootCA) > 0 {
if tlsConfig.RootCAs == nil {
tlsConfig.RootCAs = x509.NewCertPool()
}
if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCA) {
return nil, errAppendCA
}
}

// Loading Client CA File
clientCA, err := loadCertFile(c.ClientCAFile)
if err != nil {
return nil, errors.Join(errLoadClientCA, err)
}
if len(clientCA) > 0 {
if tlsConfig.ClientCAs == nil {
tlsConfig.ClientCAs = x509.NewCertPool()

switch config := any(s).(type) {
case *tls.Config:
config.Certificates = []tls.Certificate{certificate}

if len(rootCA) > 0 {
if config.RootCAs == nil {
config.RootCAs = x509.NewCertPool()
}
if !config.RootCAs.AppendCertsFromPEM(rootCA) {
return nil, errAppendCA
}
}

if len(clientCA) > 0 {
if config.ClientCAs == nil {
config.ClientCAs = x509.NewCertPool()
}
if !config.ClientCAs.AppendCertsFromPEM(clientCA) {
return nil, errAppendCA
}
config.ClientAuth = tls.RequireAndVerifyClientCert
if c.Validator != nil {
config.VerifyPeerCertificate = c.Validator
}
}
return s, nil
case *dtls.Config:
config.Certificates = []tls.Certificate{certificate}

if len(rootCA) > 0 {
if config.RootCAs == nil {
config.RootCAs = x509.NewCertPool()
}
if !config.RootCAs.AppendCertsFromPEM(rootCA) {
return nil, errAppendCA
}
}

if len(clientCA) > 0 {
if config.ClientCAs == nil {
config.ClientCAs = x509.NewCertPool()
}
if !config.ClientCAs.AppendCertsFromPEM(clientCA) {
return nil, errAppendCA
}
config.ClientAuth = dtls.RequireAndVerifyClientCert
if c.Validator != nil {
config.VerifyPeerCertificate = c.Validator
}
}
if !tlsConfig.ClientCAs.AppendCertsFromPEM(clientCA) {
return nil, errAppendCA
return s, nil
default:
return nil, errUnsupportedTLS
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring of Load function to LoadTLSConfig.

The refactoring to support both TLS and DTLS configurations improves modularity and maintainability. Ensure that MinVersion is set for both configurations to enforce secure protocol versions.

+  config.MinVersion = tls.VersionTLS13
+  config.MinVersion = dtls.VersionDTLS12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant