-
Notifications
You must be signed in to change notification settings - Fork 4
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
Conversation
…connection complete
There was a problem hiding this 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.
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 */ |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 */ |
There was a problem hiding this comment.
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
stream_id = secure_tunnel->config->service_id_3_stream_id; | ||
} else { | ||
/* service_id doesn't match any existing service id*/ | ||
AWS_LOGF_DEBUG( |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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(); |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
There was a problem hiding this 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.
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.