2
2
3
3
#[ cfg( not( target_os = "android" ) ) ]
4
4
use n0_future:: TryStreamExt ;
5
+ use nested_enum_utils:: common_fields;
6
+ use snafu:: { Backtrace , ResultExt , Snafu } ;
5
7
use tokio:: {
6
8
fs:: File ,
7
9
io:: { AsyncBufReadExt , BufReader } ,
8
10
} ;
9
11
10
12
use super :: DefaultRouteDetails ;
11
13
12
- #[ derive( Debug , thiserror:: Error ) ]
14
+ #[ common_fields( {
15
+ backtrace: Option <Backtrace >,
16
+ #[ snafu( implicit) ]
17
+ span_trace: n0_snafu:: SpanTrace ,
18
+ } ) ]
19
+ #[ derive( Debug , Snafu ) ]
20
+ #[ non_exhaustive]
13
21
pub enum Error {
14
- #[ error ( "IO {0}" ) ]
15
- Io ( # [ from ] std:: io:: Error ) ,
22
+ #[ snafu ( display ( "IO" ) ) ]
23
+ Io { source : std:: io:: Error } ,
16
24
#[ cfg( not( target_os = "android" ) ) ]
17
- #[ error ( "no netlink response" ) ]
25
+ #[ snafu ( display ( "no netlink response" ) ) ]
18
26
NoResponse ,
19
27
#[ cfg( not( target_os = "android" ) ) ]
20
- #[ error ( "interface not found" ) ]
28
+ #[ snafu ( display ( "interface not found" ) ) ]
21
29
InterfaceNotFound ,
22
- #[ error ( "iface field is missing" ) ]
30
+ #[ snafu ( display ( "iface field is missing" ) ) ]
23
31
MissingIfaceField ,
24
- #[ error ( "destination field is missing" ) ]
32
+ #[ snafu ( display ( "destination field is missing" ) ) ]
25
33
MissingDestinationField ,
26
- #[ error ( "mask field is missing" ) ]
34
+ #[ snafu ( display ( "mask field is missing" ) ) ]
27
35
MissingMaskField ,
28
36
#[ cfg( not( target_os = "android" ) ) ]
29
- #[ error ( "netlink" ) ]
30
- Netlink ( # [ from ] rtnetlink:: Error ) ,
37
+ #[ snafu ( display ( "netlink" ) ) ]
38
+ Netlink { source : rtnetlink:: Error } ,
31
39
}
32
40
33
41
pub async fn default_route ( ) -> Option < DefaultRouteDetails > {
@@ -49,7 +57,7 @@ const PROC_NET_ROUTE_PATH: &str = "/proc/net/route";
49
57
50
58
async fn default_route_proc ( ) -> Result < Option < DefaultRouteDetails > , Error > {
51
59
const ZERO_ADDR : & str = "00000000" ;
52
- let file = File :: open ( PROC_NET_ROUTE_PATH ) . await ?;
60
+ let file = File :: open ( PROC_NET_ROUTE_PATH ) . await . context ( IoSnafu ) ?;
53
61
54
62
// Explicitly set capacity, this is min(4096, DEFAULT_BUF_SIZE):
55
63
// https://github.com/google/gvisor/issues/5732
@@ -65,7 +73,7 @@ async fn default_route_proc() -> Result<Option<DefaultRouteDetails>, Error> {
65
73
// read it all in one call.
66
74
let reader = BufReader :: with_capacity ( 8 * 1024 , file) ;
67
75
let mut lines_iter = reader. lines ( ) ;
68
- while let Some ( line) = lines_iter. next_line ( ) . await ? {
76
+ while let Some ( line) = lines_iter. next_line ( ) . await . context ( IoSnafu ) ? {
69
77
if !line. contains ( ZERO_ADDR ) {
70
78
continue ;
71
79
}
@@ -127,7 +135,7 @@ fn parse_android_ip_route(stdout: &str) -> Option<&str> {
127
135
async fn default_route_netlink ( ) -> Result < Option < DefaultRouteDetails > , Error > {
128
136
use tracing:: { info_span, Instrument } ;
129
137
130
- let ( connection, handle, _receiver) = rtnetlink:: new_connection ( ) ?;
138
+ let ( connection, handle, _receiver) = rtnetlink:: new_connection ( ) . context ( IoSnafu ) ?;
131
139
let task = tokio:: spawn ( connection. instrument ( info_span ! ( "rtnetlink.conn" ) ) ) ;
132
140
133
141
let default = default_route_netlink_family ( & handle, rtnetlink:: IpVersion :: V4 ) . await ?;
@@ -151,7 +159,7 @@ async fn default_route_netlink_family(
151
159
use netlink_packet_route:: route:: RouteAttribute ;
152
160
153
161
let mut routes = handle. route ( ) . get ( family) . execute ( ) ;
154
- while let Some ( route) = routes. try_next ( ) . await ? {
162
+ while let Some ( route) = routes. try_next ( ) . await . context ( NetlinkSnafu ) ? {
155
163
let route_attrs = route. attributes ;
156
164
157
165
if !route_attrs
@@ -187,9 +195,14 @@ async fn default_route_netlink_family(
187
195
#[ cfg( not( target_os = "android" ) ) ]
188
196
async fn iface_by_index ( handle : & rtnetlink:: Handle , index : u32 ) -> Result < String , Error > {
189
197
use netlink_packet_route:: link:: LinkAttribute ;
198
+ use snafu:: OptionExt ;
190
199
191
200
let mut links = handle. link ( ) . get ( ) . match_index ( index) . execute ( ) ;
192
- let msg = links. try_next ( ) . await ?. ok_or ( Error :: NoResponse ) ?;
201
+ let msg = links
202
+ . try_next ( )
203
+ . await
204
+ . context ( NetlinkSnafu ) ?
205
+ . context ( NoResponseSnafu ) ?;
193
206
194
207
for nla in msg. attributes {
195
208
if let LinkAttribute :: IfName ( name) = nla {
0 commit comments