22#include <sys/socket.h>
33#include <netinet/in.h>
44#include <arpa/inet.h>
5+ #include <netdb.h>
6+ #include <unistd.h>
57
68#include <assert.h>
79#include <errno.h>
@@ -203,6 +205,7 @@ static void raft_entry_init(raft_entry_t *e) {
203205
204206static bool raft_log_init (raft_t raft ) {
205207 raft_log_t * l = & raft -> log ;
208+ int i ;
206209 l -> first = 0 ;
207210 l -> size = 0 ;
208211 l -> acked = 0 ;
@@ -212,20 +215,21 @@ static bool raft_log_init(raft_t raft) {
212215 shout ("failed to allocate memory for raft log\n" );
213216 return false;
214217 }
215- for (int i = 0 ; i < raft -> config .log_len ; i ++ ) {
218+ for (i = 0 ; i < raft -> config .log_len ; i ++ ) {
216219 raft_entry_init (l -> entries + i );
217220 }
218221 raft_entry_init (& l -> newentry );
219222 return true;
220223}
221224
222225static bool raft_peers_init (raft_t raft ) {
226+ int i ;
223227 raft -> peers = malloc (raft -> config .peernum_max * sizeof (raft_peer_t ));
224228 if (!raft -> peers ) {
225229 shout ("failed to allocate memory for raft peers\n" );
226230 return false;
227231 }
228- for (int i = 0 ; i < raft -> config .peernum_max ; i ++ ) {
232+ for (i = 0 ; i < raft -> config .peernum_max ; i ++ ) {
229233 raft_peer_init (raft -> peers + i );
230234 }
231235 return true;
@@ -282,27 +286,38 @@ static void raft_reset_timer(raft_t r) {
282286}
283287
284288bool 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+
285294 if (r -> peernum >= r -> config .peernum_max ) {
286295 shout ("too many peers\n" );
287296 return false;
288297 }
289298
290- raft_peer_t * p = r -> peers + id ;
291-
292299 raft_peer_init (p );
293300 p -> up = true;
294301 p -> host = host ;
295302 p -> port = port ;
296303
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+ {
298313 shout (
299314 "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 ));
302316 return false;
303317 }
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 );
306321
307322 if (self ) {
308323 if (r -> me != NOBODY ) {
@@ -352,40 +367,54 @@ static void socket_set_reuseaddr(int sock) {
352367int raft_create_udp_socket (raft_t r ) {
353368 assert (r -> me != NOBODY );
354369 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 ];
355374
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 ;
368379
369- // zero out the structure
370- memset ((char * )& me -> addr , 0 , sizeof (me -> addr ));
380+ snprintf (portstr , 6 , "%d" , me -> port );
371381
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+ {
374384 shout (
375385 "cannot convert the host string"
376386 " '%s' to a valid address\n" ,
377387 me -> host
378388 );
379389 return -1 ;
380390 }
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 ;
386412 }
387413
388- return r -> sock ;
414+ shout ("cannot resolve the host string '%s' to a valid address\n" ,
415+ me -> host
416+ );
417+ return -1 ;
389418}
390419
391420static bool msg_size_is (raft_msg_t m , int mlen ) {
@@ -500,13 +529,15 @@ static void raft_beat(raft_t r, int dst) {
500529}
501530
502531static 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 ++ ) {
504534 r -> peers [i ].acked .bytes = 0 ;
505535 }
506536}
507537
508538static 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 ++ ) {
510541 if ((i == id ) || (id == NOBODY )) {
511542 r -> peers [i ].silent_ms = 0 ;
512543 }
@@ -601,8 +632,8 @@ static void raft_refresh_acked(raft_t r) {
601632
602633static int raft_increase_silent_time (raft_t r , int ms ) {
603634 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 ++ ) {
606637 if (!r -> peers [i ].up ) continue ;
607638 if (i == r -> me ) continue ;
608639
@@ -655,9 +686,9 @@ void raft_tick(raft_t r, int msec) {
655686
656687static int raft_compact (raft_t raft ) {
657688 raft_log_t * l = & raft -> log ;
658-
689+ int i ;
659690 int compacted = 0 ;
660- for (int i = l -> first ; i < l -> applied ; i ++ ) {
691+ for (i = l -> first ; i < l -> applied ; i ++ ) {
661692 raft_entry_t * e = & RAFT_LOG (raft , i );
662693
663694 e -> snapshot = false;
@@ -677,7 +708,7 @@ static int raft_compact(raft_t raft) {
677708 assert (l -> first == l -> applied - 1 );
678709
679710 // 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 ++ ) {
681712 raft_peer_t * p = raft -> peers + i ;
682713 if (!p -> up ) continue ;
683714 if (i == raft -> me ) continue ;
@@ -735,9 +766,10 @@ bool raft_applied(raft_t r, int id, int index) {
735766}
736767
737768static bool raft_restore (raft_t r , int previndex , raft_entry_t * e ) {
769+ int i ;
738770 assert (e -> bytes == e -> update .len );
739771 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 ++ ) {
741773 raft_entry_t * victim = & RAFT_LOG (r , i );
742774 free (victim -> update .data );
743775 victim -> update .len = 0 ;
0 commit comments