Skip to content

Commit dc85824

Browse files
committed
socketforward: add bidirectional UDS forwarding
Introduce the SocketForward ttrpc service that relays UNIX domain socket connections between host and container over vsock streams. The host side (shim) parses OCI annotations to configure forwards, while the VM side (vminitd) resolves paths from its own configuration using forward identifiers. For host-to-container connections, the VM enters the target container's mount namespace via setns to dial the socket. For container-to-host connections, vminitd creates listener sockets at VM-global paths with bind mounts into the container, and streams connection notifications to the host via the Listen RPC. Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
1 parent 55bd4cf commit dc85824

File tree

14 files changed

+1863
-25
lines changed

14 files changed

+1863
-25
lines changed

api/next.txtpb

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,342 @@ file: {
850850
is_syntax_unspecified: false
851851
}
852852
}
853+
file: {
854+
name: "proto/nerdbox/services/socketforward/v1/socketforward.proto"
855+
package: "nerdbox.services.socketforward.v1"
856+
dependency: "google/protobuf/empty.proto"
857+
message_type: {
858+
name: "ConnectRequest"
859+
field: {
860+
name: "stream_id"
861+
number: 1
862+
label: LABEL_OPTIONAL
863+
type: TYPE_STRING
864+
json_name: "streamId"
865+
}
866+
field: {
867+
name: "forward_id"
868+
number: 2
869+
label: LABEL_OPTIONAL
870+
type: TYPE_STRING
871+
json_name: "forwardId"
872+
}
873+
field: {
874+
name: "container_id"
875+
number: 3
876+
label: LABEL_OPTIONAL
877+
type: TYPE_STRING
878+
json_name: "containerId"
879+
}
880+
}
881+
service: {
882+
name: "SocketForward"
883+
method: {
884+
name: "Connect"
885+
input_type: ".nerdbox.services.socketforward.v1.ConnectRequest"
886+
output_type: ".google.protobuf.Empty"
887+
}
888+
method: {
889+
name: "Listen"
890+
input_type: ".google.protobuf.Empty"
891+
output_type: ".nerdbox.services.socketforward.v1.ConnectRequest"
892+
server_streaming: true
893+
}
894+
}
895+
options: {
896+
go_package: "github.com/containerd/nerdbox/api/services/socketforward/v1;socketforward"
897+
}
898+
source_code_info: {
899+
location: {
900+
span: 16
901+
span: 0
902+
span: 73
903+
span: 1
904+
}
905+
location: {
906+
path: 12
907+
span: 16
908+
span: 0
909+
span: 18
910+
leading_detached_comments: "\nCopyright The containerd Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
911+
}
912+
location: {
913+
path: 2
914+
span: 18
915+
span: 0
916+
span: 42
917+
}
918+
location: {
919+
path: 3
920+
path: 0
921+
span: 20
922+
span: 0
923+
span: 37
924+
}
925+
location: {
926+
path: 8
927+
span: 22
928+
span: 0
929+
span: 96
930+
}
931+
location: {
932+
path: 8
933+
path: 11
934+
span: 22
935+
span: 0
936+
span: 96
937+
}
938+
location: {
939+
path: 6
940+
path: 0
941+
span: 39
942+
span: 0
943+
span: 54
944+
span: 1
945+
leading_comments: " SocketForward provides bidirectional UNIX domain socket forwarding\n across the VM boundary over vsock streams.\n\n The ttrpc server runs inside the VM (vminitd) and the ttrpc client\n runs on the host (shim). Both RPCs are initiated by the host:\n\n - Connect (host-to-container): the host asks the VM to dial a\n container-side socket on its behalf.\n - Listen (container-to-host): the host opens a server-streaming\n channel to receive notifications when a process inside the\n container connects to a forwarded socket.\n\n Socket forward entries are passed to vminitd via init args. Each\n side resolves socket paths from its own configuration using the\n forward_id.\n"
946+
}
947+
location: {
948+
path: 6
949+
path: 0
950+
path: 1
951+
span: 39
952+
span: 8
953+
span: 21
954+
}
955+
location: {
956+
path: 6
957+
path: 0
958+
path: 2
959+
path: 0
960+
span: 45
961+
span: 8
962+
span: 68
963+
leading_comments: " Connect tells the VM to dial the container-side UNIX socket\n identified by forward_id and relay data through the vsock\n stream identified by stream_id. The host must open the vsock\n stream BEFORE calling this RPC. The container_id field must\n be set so the VM can enter the container's mount namespace.\n"
964+
}
965+
location: {
966+
path: 6
967+
path: 0
968+
path: 2
969+
path: 0
970+
path: 1
971+
span: 45
972+
span: 12
973+
span: 19
974+
}
975+
location: {
976+
path: 6
977+
path: 0
978+
path: 2
979+
path: 0
980+
path: 2
981+
span: 45
982+
span: 20
983+
span: 34
984+
}
985+
location: {
986+
path: 6
987+
path: 0
988+
path: 2
989+
path: 0
990+
path: 3
991+
span: 45
992+
span: 45
993+
span: 66
994+
}
995+
location: {
996+
path: 6
997+
path: 0
998+
path: 2
999+
path: 1
1000+
span: 53
1001+
span: 8
1002+
span: 74
1003+
leading_comments: " Listen opens a server-streaming channel. When a process inside\n the container connects to a forwarded listener socket, the VM\n sends a ConnectRequest (with container_id empty). The host\n then looks up the target host socket path using forward_id\n and opens a vsock stream with the given stream_id so the\n relay can start.\n"
1004+
}
1005+
location: {
1006+
path: 6
1007+
path: 0
1008+
path: 2
1009+
path: 1
1010+
path: 1
1011+
span: 53
1012+
span: 12
1013+
span: 18
1014+
}
1015+
location: {
1016+
path: 6
1017+
path: 0
1018+
path: 2
1019+
path: 1
1020+
path: 2
1021+
span: 53
1022+
span: 19
1023+
span: 40
1024+
}
1025+
location: {
1026+
path: 6
1027+
path: 0
1028+
path: 2
1029+
path: 1
1030+
path: 6
1031+
span: 53
1032+
span: 51
1033+
span: 57
1034+
}
1035+
location: {
1036+
path: 6
1037+
path: 0
1038+
path: 2
1039+
path: 1
1040+
path: 3
1041+
span: 53
1042+
span: 58
1043+
span: 72
1044+
}
1045+
location: {
1046+
path: 4
1047+
path: 0
1048+
span: 60
1049+
span: 0
1050+
span: 73
1051+
span: 1
1052+
leading_comments: " ConnectRequest describes a forwarded connection. It is used both as\n the input to Connect (host-to-container, container_id set) and as\n the streamed output of Listen (container-to-host, container_id\n empty).\n"
1053+
}
1054+
location: {
1055+
path: 4
1056+
path: 0
1057+
path: 1
1058+
span: 60
1059+
span: 8
1060+
span: 22
1061+
}
1062+
location: {
1063+
path: 4
1064+
path: 0
1065+
path: 2
1066+
path: 0
1067+
span: 64
1068+
span: 8
1069+
span: 29
1070+
leading_comments: " ID of the vsock stream. For Connect the host opens the stream\n before calling the RPC; for Listen the host must open a stream\n with this ID after receiving the notification.\n"
1071+
}
1072+
location: {
1073+
path: 4
1074+
path: 0
1075+
path: 2
1076+
path: 0
1077+
path: 5
1078+
span: 64
1079+
span: 8
1080+
span: 14
1081+
}
1082+
location: {
1083+
path: 4
1084+
path: 0
1085+
path: 2
1086+
path: 0
1087+
path: 1
1088+
span: 64
1089+
span: 15
1090+
span: 24
1091+
}
1092+
location: {
1093+
path: 4
1094+
path: 0
1095+
path: 2
1096+
path: 0
1097+
path: 3
1098+
span: 64
1099+
span: 27
1100+
span: 28
1101+
}
1102+
location: {
1103+
path: 4
1104+
path: 0
1105+
path: 2
1106+
path: 1
1107+
span: 68
1108+
span: 8
1109+
span: 30
1110+
leading_comments: " Identifier of the socket forward entry. Each side uses this to\n resolve the socket path from its own configuration rather than\n trusting a path supplied by the other side.\n"
1111+
}
1112+
location: {
1113+
path: 4
1114+
path: 0
1115+
path: 2
1116+
path: 1
1117+
path: 5
1118+
span: 68
1119+
span: 8
1120+
span: 14
1121+
}
1122+
location: {
1123+
path: 4
1124+
path: 0
1125+
path: 2
1126+
path: 1
1127+
path: 1
1128+
span: 68
1129+
span: 15
1130+
span: 25
1131+
}
1132+
location: {
1133+
path: 4
1134+
path: 0
1135+
path: 2
1136+
path: 1
1137+
path: 3
1138+
span: 68
1139+
span: 28
1140+
span: 29
1141+
}
1142+
location: {
1143+
path: 4
1144+
path: 0
1145+
path: 2
1146+
path: 2
1147+
span: 72
1148+
span: 8
1149+
span: 32
1150+
leading_comments: " ID of the container that owns the target socket. Set by the\n host on Connect so the VM can enter the container's mount\n namespace. Empty on Listen notifications.\n"
1151+
}
1152+
location: {
1153+
path: 4
1154+
path: 0
1155+
path: 2
1156+
path: 2
1157+
path: 5
1158+
span: 72
1159+
span: 8
1160+
span: 14
1161+
}
1162+
location: {
1163+
path: 4
1164+
path: 0
1165+
path: 2
1166+
path: 2
1167+
path: 1
1168+
span: 72
1169+
span: 15
1170+
span: 27
1171+
}
1172+
location: {
1173+
path: 4
1174+
path: 0
1175+
path: 2
1176+
path: 2
1177+
path: 3
1178+
span: 72
1179+
span: 30
1180+
span: 31
1181+
}
1182+
}
1183+
syntax: "proto3"
1184+
buf_extension: {
1185+
is_import: false
1186+
is_syntax_unspecified: false
1187+
}
1188+
}
8531189
file: {
8541190
name: "proto/nerdbox/services/system/v1/info.proto"
8551191
package: "containerd.vminitd.services.system.v1"

0 commit comments

Comments
 (0)