@@ -97,6 +97,7 @@ impl AzireVpnPortForwarding {
97
97
let output_string = String :: from_utf8 ( output. stdout . clone ( ) ) ?;
98
98
log:: debug!( "AzireVPN Port forwarding list response: {}" , output_string) ;
99
99
100
+ // TODO: Distinguish error from no port forwarding existing vs. network error ?
100
101
let output_data_result: anyhow:: Result < ListResponse > = serde_json:: from_str ( & output_string)
101
102
. with_context ( || "Failed to parse JSON response from listing AzireVPN Port Forwarding" ) ;
102
103
@@ -115,32 +116,52 @@ impl AzireVpnPortForwarding {
115
116
}
116
117
117
118
// If not, create a new port forwarding
118
- let cmd = [
119
- "curl" ,
120
- "https://api.azirevpn.com/v3/portforwardings" ,
121
- "-H" ,
122
- Box :: leak ( format ! ( "Authorization: Bearer {}" , access_token) . into_boxed_str ( ) ) ,
123
- "--json" ,
124
- Box :: leak (
125
- format ! (
126
- "{{\" internal_ipv4\" : \" {}\" , \" hidden\" : false, \" expires_in\" : 30}}" ,
127
- local_ip
128
- )
129
- . into_boxed_str ( ) ,
130
- ) ,
131
- ] ;
132
-
133
- let output = NetworkNamespace :: exec_with_output ( & netns. name , & cmd) ?;
134
- let output_string = String :: from_utf8 ( output. stdout . clone ( ) ) ?;
119
+ // Retry up to 3 times
120
+
121
+ let mut i = 1 ;
122
+ let data = loop {
123
+ let cmd = [
124
+ "curl" ,
125
+ "https://api.azirevpn.com/v3/portforwardings" ,
126
+ "-H" ,
127
+ Box :: leak ( format ! ( "Authorization: Bearer {}" , access_token) . into_boxed_str ( ) ) ,
128
+ "--json" ,
129
+ Box :: leak (
130
+ format ! (
131
+ "{{\" internal_ipv4\" : \" {}\" , \" hidden\" : false, \" expires_in\" : 30}}" ,
132
+ local_ip
133
+ )
134
+ . into_boxed_str ( ) ,
135
+ ) ,
136
+ ] ;
137
+
138
+ let output = NetworkNamespace :: exec_with_output ( & netns. name , & cmd) ?;
139
+ let output_string = String :: from_utf8 ( output. stdout . clone ( ) ) ?;
140
+
141
+ log:: debug!(
142
+ "AzireVPN Port forwarding creation response: {}" ,
143
+ output_string
144
+ ) ;
145
+ let maybe_data: anyhow:: Result < CreateResponse > =
146
+ serde_json:: from_str ( output_string. as_str ( ) ) . with_context ( || {
147
+ "Failed to parse JSON response from creating AzireVPN Port Forwarding"
148
+ } ) ;
135
149
136
- log:: debug!(
137
- "AzireVPN Port forwarding creation response: {}" ,
138
- output_string
139
- ) ;
140
- let data: CreateResponse =
141
- serde_json:: from_str ( output_string. as_str ( ) ) . with_context ( || {
142
- "Failed to parse JSON response from creating AzireVPN Port Forwarding"
143
- } ) ?;
150
+ if let Ok ( data) = maybe_data {
151
+ break Ok ( data) ;
152
+ }
153
+ if i >= 3 {
154
+ log:: error!( "Failed to create AzireVPN Port Forwarding after 3 attempts" ) ;
155
+ break Err ( anyhow:: anyhow!( "Failed to create AzireVPN Port Forwarding" ) ) ;
156
+ }
157
+ log:: warn!(
158
+ "Failed to create AzireVPN Port Forwarding on attempt {}, sleeping 5 seconds and retrying" ,
159
+ i
160
+ ) ;
161
+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 5 ) ) ;
162
+
163
+ i += 1 ;
164
+ } ?;
144
165
145
166
log:: info!(
146
167
"AzireVPN Port forwarding enabled on port {}" ,
0 commit comments