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

Secure tunnel with Multiplexing #78

Merged
merged 71 commits into from
Feb 23, 2023
Merged

Secure tunnel with Multiplexing #78

merged 71 commits into from
Feb 23, 2023

Conversation

sbSteveK
Copy link
Contributor

@sbSteveK sbSteveK commented Dec 2, 2022

Secure Tunnel full refactor and Multiplexing integration

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Contributor

@bretambrose bretambrose left a comment

Choose a reason for hiding this comment

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

First pass on everything except secure_tunneling.c For that one I need to read it on its own without any diff, it's too overwhelming otherwise.

include/aws/iotdevice/private/serializer.h Outdated Show resolved Hide resolved
include/aws/iotdevice/private/serializer.h Outdated Show resolved Hide resolved
struct aws_byte_buf payload;
enum aws_secure_tunnel_protocol_buffer_wire_type {
AWS_SECURE_TUNNEL_PBWT_VARINT = 0, /* int32, int64, uint32, uint64, sint32, sint64, bool, enum */
AWS_SECURE_TUNNEL_PBWT_64_BIT = 1, /* fixed64, sfixed64, double */
Copy link
Contributor

Choose a reason for hiding this comment

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

If these are all floating point, I'd make that part of the name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way protocol buffers work, type 1 and type 5 refer to the size of what comes next and we handle casting those bits as one of the types in the comment. They're not always doubles/floats and can also be ints and uints. I think we should leave them as is but don't feel strongly about it and am open to naming them something else if you do.

FWIW, we also don't use either in our encoding/decoding for secure tunnel.

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like our implementation should not care about protocol buffers in any way. It's... frustrating that someone is defining an abstract network wire protocol in terms of a specific technology.

AWS_SECURE_TUNNEL_PBWT_LENGTH_DELIMINTED = 2, /* string, bytes, embedded messages, packed repeated fields */
AWS_SECURE_TUNNEL_PBWT_START_GROUP = 3, /* groups (deprecated) */
AWS_SECURE_TUNNEL_PBWT_END_GROUP = 4, /* groups (deprecated) */
AWS_SECURE_TUNNEL_PBWT_32_BIT = 5, /* fixed32, sfixed32, float */
Copy link
Contributor

Choose a reason for hiding this comment

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

If these are all floating point, I'd make that part of the name

source/secure_tunneling_operations.c Outdated Show resolved Hide resolved
stream_id = secure_tunnel->config->service_id_3_stream_id;
} else {
/* service_id doesn't match any existing service id*/
AWS_LOGF_DEBUG(
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be a fatal protocol error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tricky. It's possible the user uses a service id that isn't one the current secure tunnel supports. The protocol/specs for secure tunnel doesn't explicitly say anything about what to do in this scenario so I'm just letting it slide with a debug message. I could maybe swap it to a Warn level message instead of Debug.

* Check the outbound stream start service id (or lack of one for V1) and set the secure tunnel and stream start
* message's stream id to the next value.
*/
static int s_aws_secure_tunnel_operation_message_set_next_stream_id(
Copy link
Contributor

Choose a reason for hiding this comment

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

Comments above apply to this function too.

Also, I just don't understand the semantics of this function. It takes a service id (as specified in a message) and then uses a different, larger stream id (written back into that message) than what is assigned to that service id. Larger context of why this is happening would be helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Destination device connects, receives service ids (multiplexing) from the service, and each of the (up to 3) service id's stream ids are set to 0 (unused).

When a Source device connects on the other end of the tunnel, it starts a stream by sending a service id along with whatever number they want as the stream id.

When the function above (s_aws_secure_tunnel_operation_message_set_stream_id) receives a stream start message, it checks against the service ids, and sets that service id's stream id to the received one from the stream start.

This function here (s_aws_secure_tunnel_operation_message_set_next_stream_id ) is only called from Source mode sending a Stream Start message and it gets the next stream id to use and sets a its own stream id to the same one so it can send messages and receive messages on the right stream id.

source/secure_tunneling_operations.c Show resolved Hide resolved
source/secure_tunneling_operations.c Outdated Show resolved Hide resolved
include/aws/iotdevice/secure_tunneling.h Outdated Show resolved Hide resolved
AWS_IOTDEVICE_API
const struct aws_secure_tunnel_options *aws_secure_tunnel_options_storage_get(
const struct aws_secure_tunnel_options_storage *storage);
int aws_secure_tunnel_stream_start(
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be replaced by a start followed by a send_message?

Can these functions marked don't-use be moved to a private header? Private header APIs are accessible from tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Stream Start is a specific operation that's processed differently than a message. It obtains the stream id differently and I'm assuming this will need to be expanded further for V3.

I thought about moving them to a private header but we still need to support this in a way that prevents breaking existing use in CPP because it was exposed. This one feels like a gray area in terms of how we want to handle it but for now, I'll leave it here since it needs to be accessible by the CPP client.

source/serializer.c Show resolved Hide resolved
source/secure_tunneling_operations.c Outdated Show resolved Hide resolved
case AWS_STOT_STREAM_START:
if ((*current_operation->vtable->aws_secure_tunnel_operation_set_next_stream_id_fn)(
current_operation, secure_tunnel)) {
error_code = aws_last_error();
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, it's hard to conceive of a sane protocol that continues under invariant breakage (or what should be an invariant)


if ((*current_operation->vtable->aws_secure_tunnel_operation_assign_stream_id_fn)(
current_operation, secure_tunnel)) {
error_code = aws_last_error();
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, it's hard to conceive of a sane protocol that continues under invariant breakage (or what should be an invariant)

break;
}

s_complete_operation(secure_tunnel, current_operation, AWS_OP_SUCCESS, NULL);
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems weird. We're guaranteed to fully flush an application data message?

Actually I think I understand now. In mqtt5 we're using raw channel messages of a fixed size. Here we're sending var-length websocket frames and the websocket impl is responsible for breaking up into channel messages.

source/secure_tunneling.c Show resolved Hide resolved
source/secure_tunneling.c Outdated Show resolved Hide resolved
Copy link
Contributor

@TwistedTwigleg TwistedTwigleg left a comment

Choose a reason for hiding this comment

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

Review part 1:

I have not looked at secure_tunneling.c, secure_tunneling_operations.c, nor serializer.c yet - but I will look at those next. So far it looks good though! Will look at the files mentioned on my next review pass.

bin/securetunnel/main.c Outdated Show resolved Hide resolved
bin/securetunnel/main.c Outdated Show resolved Hide resolved
bin/securetunnel/main.c Outdated Show resolved Hide resolved
bin/securetunnel/main.c Outdated Show resolved Hide resolved
bin/securetunnel/main.c Outdated Show resolved Hide resolved
tests/secure_tunnel_tests.c Outdated Show resolved Hide resolved
tests/secure_tunnel_tests.c Outdated Show resolved Hide resolved
tests/secure_tunnel_tests.c Outdated Show resolved Hide resolved
tests/secure_tunnel_tests.c Outdated Show resolved Hide resolved
tests/secure_tunneling_tests.c Outdated Show resolved Hide resolved
Copy link
Contributor

@TwistedTwigleg TwistedTwigleg left a comment

Choose a reason for hiding this comment

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

Review Part 2: Some minor questions and nitpick/debatable things that might be worth looking into (or not!) - but they are all minor and the rest looks good.

source/serializer.c Show resolved Hide resolved
source/serializer.c Show resolved Hide resolved
source/serializer.c Show resolved Hide resolved
source/serializer.c Outdated Show resolved Hide resolved
source/secure_tunneling_operations.c Show resolved Hide resolved
source/secure_tunneling.c Outdated Show resolved Hide resolved
source/secure_tunneling.c Show resolved Hide resolved
source/secure_tunneling.c Show resolved Hide resolved
source/secure_tunneling.c Show resolved Hide resolved
source/secure_tunneling.c Show resolved Hide resolved
@sbSteveK sbSteveK merged commit 09ded2b into main Feb 23, 2023
@sbSteveK sbSteveK deleted the secure-tunnel-multiplex branch February 23, 2023 22:23
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.

3 participants