2
2
#include <sys/socket.h>
3
3
#include <netinet/in.h>
4
4
#include <arpa/inet.h>
5
+ #include <netdb.h>
6
+ #include <unistd.h>
5
7
6
8
#include <assert.h>
7
9
#include <errno.h>
@@ -203,6 +205,7 @@ static void raft_entry_init(raft_entry_t *e) {
203
205
204
206
static bool raft_log_init (raft_t raft ) {
205
207
raft_log_t * l = & raft -> log ;
208
+ int i ;
206
209
l -> first = 0 ;
207
210
l -> size = 0 ;
208
211
l -> acked = 0 ;
@@ -212,20 +215,21 @@ static bool raft_log_init(raft_t raft) {
212
215
shout ("failed to allocate memory for raft log\n" );
213
216
return false;
214
217
}
215
- for (int i = 0 ; i < raft -> config .log_len ; i ++ ) {
218
+ for (i = 0 ; i < raft -> config .log_len ; i ++ ) {
216
219
raft_entry_init (l -> entries + i );
217
220
}
218
221
raft_entry_init (& l -> newentry );
219
222
return true;
220
223
}
221
224
222
225
static bool raft_peers_init (raft_t raft ) {
226
+ int i ;
223
227
raft -> peers = malloc (raft -> config .peernum_max * sizeof (raft_peer_t ));
224
228
if (!raft -> peers ) {
225
229
shout ("failed to allocate memory for raft peers\n" );
226
230
return false;
227
231
}
228
- for (int i = 0 ; i < raft -> config .peernum_max ; i ++ ) {
232
+ for (i = 0 ; i < raft -> config .peernum_max ; i ++ ) {
229
233
raft_peer_init (raft -> peers + i );
230
234
}
231
235
return true;
@@ -282,27 +286,38 @@ static void raft_reset_timer(raft_t r) {
282
286
}
283
287
284
288
bool raft_peer_up (raft_t r , int id , char * host , int port , bool self ) {
289
+ raft_peer_t * p = r -> peers + id ;
290
+ struct addrinfo hint ;
291
+ struct addrinfo * a = NULL ;
292
+ char portstr [6 ];
293
+
285
294
if (r -> peernum >= r -> config .peernum_max ) {
286
295
shout ("too many peers\n" );
287
296
return false;
288
297
}
289
298
290
- raft_peer_t * p = r -> peers + id ;
291
-
292
299
raft_peer_init (p );
293
300
p -> up = true;
294
301
p -> host = host ;
295
302
p -> port = port ;
296
303
297
- if (inet_aton (p -> host , & p -> addr .sin_addr ) == 0 ) {
304
+ memset (& hint , 0 , sizeof (hint ));
305
+ hint .ai_socktype = SOCK_DGRAM ;
306
+ hint .ai_family = AF_INET ;
307
+ hint .ai_protocol = getprotobyname ("udp" )-> p_proto ;
308
+
309
+ snprintf (portstr , 6 , "%d" , port );
310
+
311
+ if (getaddrinfo (host , portstr , & hint , & a ))
312
+ {
298
313
shout (
299
314
"cannot convert the host string '%s'"
300
- " to a valid address\n" , p -> host
301
- );
315
+ " to a valid address: %s\n" , host , strerror (errno ));
302
316
return false;
303
317
}
304
- p -> addr .sin_family = AF_INET ;
305
- p -> addr .sin_port = htons (p -> port );
318
+
319
+ assert (a != NULL && a -> ai_addrlen <= sizeof (p -> addr ));
320
+ memcpy (& p -> addr , a -> ai_addr , a -> ai_addrlen );
306
321
307
322
if (self ) {
308
323
if (r -> me != NOBODY ) {
@@ -352,40 +367,54 @@ static void socket_set_reuseaddr(int sock) {
352
367
int raft_create_udp_socket (raft_t r ) {
353
368
assert (r -> me != NOBODY );
354
369
raft_peer_t * me = r -> peers + r -> me ;
370
+ struct addrinfo hint ;
371
+ struct addrinfo * addrs = NULL ;
372
+ struct addrinfo * a ;
373
+ char portstr [6 ];
355
374
356
- r -> sock = socket (AF_INET , SOCK_DGRAM , IPPROTO_UDP );
357
- if (r -> sock == -1 ) {
358
- shout (
359
- "cannot create the listening"
360
- " socket: %s\n" ,
361
- strerror (errno )
362
- );
363
- return -1 ;
364
- }
365
-
366
- socket_set_reuseaddr (r -> sock );
367
- socket_set_recv_timeout (r -> sock , r -> config .heartbeat_ms );
375
+ memset (& hint , 0 , sizeof (hint ));
376
+ hint .ai_socktype = SOCK_DGRAM ;
377
+ hint .ai_family = AF_INET ;
378
+ hint .ai_protocol = getprotobyname ("udp" )-> p_proto ;
368
379
369
- // zero out the structure
370
- memset ((char * )& me -> addr , 0 , sizeof (me -> addr ));
380
+ snprintf (portstr , 6 , "%d" , me -> port );
371
381
372
- me -> addr . sin_family = AF_INET ;
373
- if ( inet_aton ( me -> host , & me -> addr . sin_addr ) == 0 ) {
382
+ if ( getaddrinfo ( me -> host , portstr , & hint , & addrs ))
383
+ {
374
384
shout (
375
385
"cannot convert the host string"
376
386
" '%s' to a valid address\n" ,
377
387
me -> host
378
388
);
379
389
return -1 ;
380
390
}
381
- me -> addr .sin_port = htons (me -> port );
382
- debug ("binding udp %s:%d\n" , me -> host , me -> port );
383
- if (bind (r -> sock , (struct sockaddr * )& me -> addr , sizeof (me -> addr )) == -1 ) {
384
- shout ("cannot bind the socket: %s\n" , strerror (errno ));
385
- return -1 ;
391
+
392
+ for (a = addrs ; a != NULL ; a = a -> ai_next )
393
+ {
394
+ int sock = socket (AF_INET , SOCK_DGRAM , IPPROTO_UDP );
395
+ if (sock < 0 ) {
396
+ shout ("cannot create socket: %s\n" , strerror (errno ));
397
+ continue ;
398
+ }
399
+ socket_set_reuseaddr (sock );
400
+ socket_set_recv_timeout (sock , r -> config .heartbeat_ms );
401
+
402
+ debug ("binding udp %s:%d\n" , me -> host , me -> port );
403
+ if (bind (sock , a -> ai_addr , a -> ai_addrlen ) < 0 ) {
404
+ shout ("cannot bind the socket: %s\n" , strerror (errno ));
405
+ close (sock );
406
+ continue ;
407
+ }
408
+ r -> sock = sock ;
409
+ assert (a -> ai_addrlen <= sizeof (me -> addr ));
410
+ memcpy (& me -> addr , a -> ai_addr , a -> ai_addrlen );
411
+ return sock ;
386
412
}
387
413
388
- return r -> sock ;
414
+ shout ("cannot resolve the host string '%s' to a valid address\n" ,
415
+ me -> host
416
+ );
417
+ return -1 ;
389
418
}
390
419
391
420
static bool msg_size_is (raft_msg_t m , int mlen ) {
@@ -500,13 +529,15 @@ static void raft_beat(raft_t r, int dst) {
500
529
}
501
530
502
531
static void raft_reset_bytes_acked (raft_t r ) {
503
- for (int i = 0 ; i < r -> config .peernum_max ; i ++ ) {
532
+ int i ;
533
+ for (i = 0 ; i < r -> config .peernum_max ; i ++ ) {
504
534
r -> peers [i ].acked .bytes = 0 ;
505
535
}
506
536
}
507
537
508
538
static void raft_reset_silent_time (raft_t r , int id ) {
509
- for (int i = 0 ; i < r -> config .peernum_max ; i ++ ) {
539
+ int i ;
540
+ for (i = 0 ; i < r -> config .peernum_max ; i ++ ) {
510
541
if ((i == id ) || (id == NOBODY )) {
511
542
r -> peers [i ].silent_ms = 0 ;
512
543
}
@@ -601,8 +632,8 @@ static void raft_refresh_acked(raft_t r) {
601
632
602
633
static int raft_increase_silent_time (raft_t r , int ms ) {
603
634
int recent_peers = 1 ; // count myself as recent
604
-
605
- for (int i = 0 ; i < r -> config .peernum_max ; i ++ ) {
635
+ int i ;
636
+ for (i = 0 ; i < r -> config .peernum_max ; i ++ ) {
606
637
if (!r -> peers [i ].up ) continue ;
607
638
if (i == r -> me ) continue ;
608
639
@@ -655,9 +686,9 @@ void raft_tick(raft_t r, int msec) {
655
686
656
687
static int raft_compact (raft_t raft ) {
657
688
raft_log_t * l = & raft -> log ;
658
-
689
+ int i ;
659
690
int compacted = 0 ;
660
- for (int i = l -> first ; i < l -> applied ; i ++ ) {
691
+ for (i = l -> first ; i < l -> applied ; i ++ ) {
661
692
raft_entry_t * e = & RAFT_LOG (raft , i );
662
693
663
694
e -> snapshot = false;
@@ -677,7 +708,7 @@ static int raft_compact(raft_t raft) {
677
708
assert (l -> first == l -> applied - 1 );
678
709
679
710
// reset bytes progress of peers that were receiving the compacted entries
680
- for (int i = 0 ; i < raft -> config .peernum_max ; i ++ ) {
711
+ for (i = 0 ; i < raft -> config .peernum_max ; i ++ ) {
681
712
raft_peer_t * p = raft -> peers + i ;
682
713
if (!p -> up ) continue ;
683
714
if (i == raft -> me ) continue ;
@@ -735,9 +766,10 @@ bool raft_applied(raft_t r, int id, int index) {
735
766
}
736
767
737
768
static bool raft_restore (raft_t r , int previndex , raft_entry_t * e ) {
769
+ int i ;
738
770
assert (e -> bytes == e -> update .len );
739
771
assert (e -> snapshot );
740
- for (int i = RAFT_LOG_FIRST_INDEX (r ); i <= RAFT_LOG_LAST_INDEX (r ); i ++ ) {
772
+ for (i = RAFT_LOG_FIRST_INDEX (r ); i <= RAFT_LOG_LAST_INDEX (r ); i ++ ) {
741
773
raft_entry_t * victim = & RAFT_LOG (r , i );
742
774
free (victim -> update .data );
743
775
victim -> update .len = 0 ;
0 commit comments