@@ -6,8 +6,6 @@ use super::ext::{in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_sin6_scope_id};
6
6
use crate :: ffi:: CStr ;
7
7
use crate :: io;
8
8
use crate :: net:: { Ipv4Addr , Ipv6Addr , SocketAddrAny , SocketAddrV4 , SocketAddrV6 } ;
9
- #[ cfg( not( windows) ) ]
10
- use alloc:: vec:: Vec ;
11
9
use core:: mem:: size_of;
12
10
13
11
// This must match the header of `sockaddr`.
@@ -61,7 +59,7 @@ pub(crate) unsafe fn read_sockaddr(
61
59
if len < size_of :: < c:: sockaddr_in > ( ) {
62
60
return Err ( io:: Errno :: INVAL ) ;
63
61
}
64
- let decode = * storage. cast :: < c:: sockaddr_in > ( ) ;
62
+ let decode = & * storage. cast :: < c:: sockaddr_in > ( ) ;
65
63
Ok ( SocketAddrAny :: V4 ( SocketAddrV4 :: new (
66
64
Ipv4Addr :: from ( u32:: from_be ( in_addr_s_addr ( decode. sin_addr ) ) ) ,
67
65
u16:: from_be ( decode. sin_port ) ,
@@ -71,7 +69,7 @@ pub(crate) unsafe fn read_sockaddr(
71
69
if len < size_of :: < c:: sockaddr_in6 > ( ) {
72
70
return Err ( io:: Errno :: INVAL ) ;
73
71
}
74
- let decode = * storage. cast :: < c:: sockaddr_in6 > ( ) ;
72
+ let decode = & * storage. cast :: < c:: sockaddr_in6 > ( ) ;
75
73
#[ cfg( not( windows) ) ]
76
74
let s6_addr = decode. sin6_addr . s6_addr ;
77
75
#[ cfg( windows) ]
@@ -93,20 +91,40 @@ pub(crate) unsafe fn read_sockaddr(
93
91
return Err ( io:: Errno :: INVAL ) ;
94
92
}
95
93
if len == offsetof_sun_path {
96
- Ok ( SocketAddrAny :: Unix ( SocketAddrUnix :: new ( & [ ] [ ..] ) . unwrap ( ) ) )
94
+ SocketAddrUnix :: new ( & [ ] [ ..] ) . map ( SocketAddrAny :: Unix )
97
95
} else {
98
- let decode = * storage. cast :: < c:: sockaddr_un > ( ) ;
96
+ let decode = & * storage. cast :: < c:: sockaddr_un > ( ) ;
97
+
98
+ // On Linux check for Linux's [abstract namespace].
99
+ //
100
+ // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html
101
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
102
+ if decode. sun_path [ 0 ] == 0 {
103
+ return SocketAddrUnix :: new_abstract_name ( core:: mem:: transmute :: <
104
+ & [ c:: c_char ] ,
105
+ & [ u8 ] ,
106
+ > (
107
+ & decode. sun_path [ 1 ..len - offsetof_sun_path] ,
108
+ ) )
109
+ . map ( SocketAddrAny :: Unix ) ;
110
+ }
111
+
112
+ // Otherwise we expect a NUL-terminated filesystem path.
99
113
100
114
// Trim off unused bytes from the end of `path_bytes`.
101
115
let path_bytes = if cfg ! ( target_os = "freebsd" ) {
102
116
// FreeBSD sometimes sets the length to longer than the length
103
117
// of the NUL-terminated string. Find the NUL and truncate the
104
118
// string accordingly.
105
- & decode. sun_path [ ..decode. sun_path . iter ( ) . position ( |b| * b == 0 ) . unwrap ( ) ]
119
+ & decode. sun_path [ ..decode
120
+ . sun_path
121
+ . iter ( )
122
+ . position ( |b| * b == 0 )
123
+ . ok_or ( io:: Errno :: INVAL ) ?]
106
124
} else {
107
125
// Otherwise, use the provided length.
108
126
let provided_len = len - 1 - offsetof_sun_path;
109
- if decode. sun_path [ provided_len] != b'\0' as c :: c_char {
127
+ if decode. sun_path [ provided_len] != 0 {
110
128
return Err ( io:: Errno :: INVAL ) ;
111
129
}
112
130
debug_assert_eq ! (
@@ -116,10 +134,8 @@ pub(crate) unsafe fn read_sockaddr(
116
134
& decode. sun_path [ ..provided_len]
117
135
} ;
118
136
119
- Ok ( SocketAddrAny :: Unix (
120
- SocketAddrUnix :: new ( path_bytes. iter ( ) . map ( |c| * c as u8 ) . collect :: < Vec < u8 > > ( ) )
121
- . unwrap ( ) ,
122
- ) )
137
+ SocketAddrUnix :: new ( core:: mem:: transmute :: < & [ c:: c_char ] , & [ u8 ] > ( path_bytes) )
138
+ . map ( SocketAddrAny :: Unix )
123
139
}
124
140
}
125
141
_ => Err ( io:: Errno :: INVAL ) ,
@@ -164,15 +180,15 @@ unsafe fn inner_read_sockaddr_os(
164
180
match family {
165
181
c:: AF_INET => {
166
182
assert ! ( len >= size_of:: <c:: sockaddr_in>( ) ) ;
167
- let decode = * storage. cast :: < c:: sockaddr_in > ( ) ;
183
+ let decode = & * storage. cast :: < c:: sockaddr_in > ( ) ;
168
184
SocketAddrAny :: V4 ( SocketAddrV4 :: new (
169
185
Ipv4Addr :: from ( u32:: from_be ( in_addr_s_addr ( decode. sin_addr ) ) ) ,
170
186
u16:: from_be ( decode. sin_port ) ,
171
187
) )
172
188
}
173
189
c:: AF_INET6 => {
174
190
assert ! ( len >= size_of:: <c:: sockaddr_in6>( ) ) ;
175
- let decode = * storage. cast :: < c:: sockaddr_in6 > ( ) ;
191
+ let decode = & * storage. cast :: < c:: sockaddr_in6 > ( ) ;
176
192
SocketAddrAny :: V6 ( SocketAddrV6 :: new (
177
193
Ipv6Addr :: from ( in6_addr_s6_addr ( decode. sin6_addr ) ) ,
178
194
u16:: from_be ( decode. sin6_port ) ,
@@ -186,51 +202,38 @@ unsafe fn inner_read_sockaddr_os(
186
202
if len == offsetof_sun_path {
187
203
SocketAddrAny :: Unix ( SocketAddrUnix :: new ( & [ ] [ ..] ) . unwrap ( ) )
188
204
} else {
189
- #[ cfg( not( any( target_os = "android" , target_os = "linux" ) ) ) ]
190
- fn try_decode_abstract_socket (
191
- _sockaddr : & c:: sockaddr_un ,
192
- _len : usize ,
193
- ) -> Option < SocketAddrUnix > {
194
- None
195
- }
205
+ let decode = & * storage. cast :: < c:: sockaddr_un > ( ) ;
206
+
207
+ // On Linux check for Linux's [abstract namespace].
208
+ //
209
+ // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html
196
210
#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
197
- fn try_decode_abstract_socket (
198
- decode : & c:: sockaddr_un ,
199
- len : usize ,
200
- ) -> Option < SocketAddrUnix > {
201
- if decode. sun_path [ 0 ] != 0 {
202
- None
203
- } else {
204
- let offsetof_sun_path = super :: addr:: offsetof_sun_path ( ) ;
205
- let address_bytes = & decode. sun_path [ 1 ..len - offsetof_sun_path] ;
206
- Some (
207
- SocketAddrUnix :: new_abstract_name (
208
- & address_bytes. iter ( ) . map ( |c| * c as u8 ) . collect :: < Vec < u8 > > ( ) ,
209
- )
210
- . unwrap ( ) ,
211
- )
212
- }
211
+ if decode. sun_path [ 0 ] == 0 {
212
+ return SocketAddrAny :: Unix (
213
+ SocketAddrUnix :: new_abstract_name ( core:: mem:: transmute :: <
214
+ & [ c:: c_char ] ,
215
+ & [ u8 ] ,
216
+ > (
217
+ & decode. sun_path [ 1 ..len - offsetof_sun_path] ,
218
+ ) )
219
+ . unwrap ( ) ,
220
+ ) ;
213
221
}
214
222
215
- let decode = * storage. cast :: < c:: sockaddr_un > ( ) ;
216
- let result = try_decode_abstract_socket ( & decode, len) . unwrap_or_else ( || {
217
- assert_eq ! (
218
- decode. sun_path[ len - 1 - offsetof_sun_path] ,
219
- b'\0' as c:: c_char
220
- ) ;
221
- let path_bytes = & decode. sun_path [ ..len - 1 - offsetof_sun_path] ;
223
+ // Otherwise we expect a NUL-terminated filesystem path.
224
+ assert_eq ! ( decode. sun_path[ len - 1 - offsetof_sun_path] , 0 ) ;
225
+ let path_bytes = & decode. sun_path [ ..len - 1 - offsetof_sun_path] ;
222
226
223
- // FreeBSD sometimes sets the length to longer than the length
224
- // of the NUL-terminated string. Find the NUL and truncate the
225
- // string accordingly.
226
- #[ cfg( target_os = "freebsd" ) ]
227
- let path_bytes =
228
- & path_bytes[ ..path_bytes. iter ( ) . position ( |b| * b == 0 ) . unwrap ( ) ] ;
229
-
230
- SocketAddrUnix :: new ( path_bytes. iter ( ) . map ( |c| * c as u8 ) . collect :: < Vec < u8 > > ( ) )
231
- . unwrap ( )
232
- } ) ;
233
- SocketAddrAny :: Unix ( result)
227
+ // FreeBSD sometimes sets the length to longer than the length
228
+ // of the NUL-terminated string. Find the NUL and truncate the
229
+ // string accordingly.
230
+ #[ cfg( target_os = "freebsd" ) ]
231
+ let path_bytes = & path_bytes[ ..path_bytes. iter ( ) . position ( |b| * b == 0 ) . unwrap ( ) ] ;
232
+
233
+ SocketAddrAny :: Unix (
234
+ SocketAddrUnix :: new ( core:: mem:: transmute :: < & [ c:: c_char ] , & [ u8 ] > ( path_bytes) )
235
+ . unwrap ( ) ,
236
+ )
234
237
}
235
238
}
236
239
other => unimplemented ! ( "{:?}" , other) ,
0 commit comments