@@ -24,6 +24,8 @@ use ::sys::socket::addr::sys_control::SysControlAddr;
24
24
target_os = "netbsd" ,
25
25
target_os = "openbsd" ) ) ]
26
26
pub use self :: datalink:: LinkAddr ;
27
+ #[ cfg( target_os = "linux" ) ]
28
+ pub use self :: vsock:: VsockAddr ;
27
29
28
30
/// These constants specify the protocol family to be used
29
31
/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
@@ -241,6 +243,8 @@ impl AddressFamily {
241
243
target_os = "netbsd" ,
242
244
target_os = "openbsd" ) ) ]
243
245
libc:: AF_LINK => Some ( AddressFamily :: Link ) ,
246
+ #[ cfg( target_os = "linux" ) ]
247
+ libc:: AF_VSOCK => Some ( AddressFamily :: Vsock ) ,
244
248
_ => None
245
249
}
246
250
}
@@ -638,7 +642,9 @@ pub enum SockAddr {
638
642
target_os = "macos" ,
639
643
target_os = "netbsd" ,
640
644
target_os = "openbsd" ) ) ]
641
- Link ( LinkAddr )
645
+ Link ( LinkAddr ) ,
646
+ #[ cfg( target_os = "linux" ) ]
647
+ Vsock ( VsockAddr ) ,
642
648
}
643
649
644
650
impl SockAddr {
@@ -665,6 +671,11 @@ impl SockAddr {
665
671
SysControlAddr :: from_name ( sockfd, name, unit) . map ( |a| SockAddr :: SysControl ( a) )
666
672
}
667
673
674
+ #[ cfg( target_os = "linux" ) ]
675
+ pub fn new_vsock ( cid : u32 , port : u32 ) -> SockAddr {
676
+ SockAddr :: Vsock ( VsockAddr :: new ( cid, port) )
677
+ }
678
+
668
679
pub fn family ( & self ) -> AddressFamily {
669
680
match * self {
670
681
SockAddr :: Inet ( InetAddr :: V4 ( ..) ) => AddressFamily :: Inet ,
@@ -684,7 +695,9 @@ impl SockAddr {
684
695
target_os = "macos" ,
685
696
target_os = "netbsd" ,
686
697
target_os = "openbsd" ) ) ]
687
- SockAddr :: Link ( ..) => AddressFamily :: Link
698
+ SockAddr :: Link ( ..) => AddressFamily :: Link ,
699
+ #[ cfg( target_os = "linux" ) ]
700
+ SockAddr :: Vsock ( ..) => AddressFamily :: Vsock ,
688
701
}
689
702
}
690
703
@@ -729,6 +742,9 @@ impl SockAddr {
729
742
Some ( SockAddr :: Link ( ether_addr) )
730
743
}
731
744
} ,
745
+ #[ cfg( target_os = "linux" ) ]
746
+ Some ( AddressFamily :: Vsock ) => Some ( SockAddr :: Vsock (
747
+ VsockAddr ( * ( addr as * const libc:: sockaddr_vm ) ) ) ) ,
732
748
// Other address families are currently not supported and simply yield a None
733
749
// entry instead of a proper conversion to a `SockAddr`.
734
750
Some ( _) | None => None ,
@@ -763,6 +779,8 @@ impl SockAddr {
763
779
target_os = "netbsd" ,
764
780
target_os = "openbsd" ) ) ]
765
781
SockAddr :: Link ( LinkAddr ( ref ether_addr) ) => ( mem:: transmute ( ether_addr) , mem:: size_of :: < libc:: sockaddr_dl > ( ) as libc:: socklen_t ) ,
782
+ #[ cfg( target_os = "linux" ) ]
783
+ SockAddr :: Vsock ( VsockAddr ( ref sa) ) => ( mem:: transmute ( sa) , mem:: size_of :: < libc:: sockaddr_vm > ( ) as libc:: socklen_t ) ,
766
784
}
767
785
}
768
786
}
@@ -786,7 +804,9 @@ impl fmt::Display for SockAddr {
786
804
target_os = "macos" ,
787
805
target_os = "netbsd" ,
788
806
target_os = "openbsd" ) ) ]
789
- SockAddr :: Link ( ref ether_addr) => ether_addr. fmt ( f)
807
+ SockAddr :: Link ( ref ether_addr) => ether_addr. fmt ( f) ,
808
+ #[ cfg( target_os = "linux" ) ]
809
+ SockAddr :: Vsock ( ref svm) => svm. fmt ( f) ,
790
810
}
791
811
}
792
812
}
@@ -1124,6 +1144,66 @@ mod datalink {
1124
1144
}
1125
1145
}
1126
1146
1147
+ #[ cfg( target_os = "linux" ) ]
1148
+ pub mod vsock {
1149
+ use :: sys:: socket:: addr:: AddressFamily ;
1150
+ use libc:: { sa_family_t, sockaddr_vm} ;
1151
+ use std:: { fmt, mem} ;
1152
+ use std:: hash:: { Hash , Hasher } ;
1153
+
1154
+ #[ derive( Copy , Clone ) ]
1155
+ pub struct VsockAddr ( pub sockaddr_vm ) ;
1156
+
1157
+ // , PartialEq, Eq, Debug, Hash
1158
+ impl PartialEq for VsockAddr {
1159
+ fn eq ( & self , other : & Self ) -> bool {
1160
+ let ( inner, other) = ( self . 0 , other. 0 ) ;
1161
+ ( inner. svm_family , inner. svm_cid , inner. svm_port ) ==
1162
+ ( other. svm_family , other. svm_cid , other. svm_port )
1163
+ }
1164
+ }
1165
+
1166
+ impl Eq for VsockAddr { }
1167
+
1168
+ impl Hash for VsockAddr {
1169
+ fn hash < H : Hasher > ( & self , s : & mut H ) {
1170
+ let inner = self . 0 ;
1171
+ ( inner. svm_family , inner. svm_cid , inner. svm_port ) . hash ( s) ;
1172
+ }
1173
+ }
1174
+
1175
+ impl VsockAddr {
1176
+ pub fn new ( cid : u32 , port : u32 ) -> VsockAddr {
1177
+ let mut addr: sockaddr_vm = unsafe { mem:: zeroed ( ) } ;
1178
+ addr. svm_family = AddressFamily :: Vsock as sa_family_t ;
1179
+ addr. svm_cid = cid;
1180
+ addr. svm_port = port;
1181
+
1182
+ VsockAddr ( addr)
1183
+ }
1184
+
1185
+ pub fn cid ( & self ) -> u32 {
1186
+ self . 0 . svm_cid
1187
+ }
1188
+
1189
+ pub fn port ( & self ) -> u32 {
1190
+ self . 0 . svm_port
1191
+ }
1192
+ }
1193
+
1194
+ impl fmt:: Display for VsockAddr {
1195
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1196
+ write ! ( f, "cid: {} port: {}" , self . cid( ) , self . port( ) )
1197
+ }
1198
+ }
1199
+
1200
+ impl fmt:: Debug for VsockAddr {
1201
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1202
+ fmt:: Display :: fmt ( self , f)
1203
+ }
1204
+ }
1205
+ }
1206
+
1127
1207
#[ cfg( test) ]
1128
1208
mod tests {
1129
1209
#[ cfg( any( target_os = "android" ,
0 commit comments