Ticket #12319: 0001-updated-ntp-to-use-getaddrinfo.patch

File 0001-updated-ntp-to-use-getaddrinfo.patch, 4.1 KB (added by a-star, 7 years ago)

Updated ntp to use getaddrinfo

  • src/preferences/time/ntp.cpp

    From 1b14f9022c5b37b681599cf6beffcb6c82ca479e Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Mon, 20 Mar 2017 18:33:14 +0530
    Subject: [PATCH] updated ntp to use getaddrinfo
    
    ---
     src/preferences/time/ntp.cpp | 73 ++++++++++++++++++++++++++++++--------------
     1 file changed, 50 insertions(+), 23 deletions(-)
    
    diff --git a/src/preferences/time/ntp.cpp b/src/preferences/time/ntp.cpp
    index 167ef2c..553aaed 100644
    a b  
    66
    77#include "ntp.h"
    88
     9#include <sys/types.h>
     10#include <netdb.h>
     11#include <arpa/inet.h>
     12
    913#include <errno.h>
    1014#include <netdb.h>
    1115#include <string.h>
    struct ntp_data {  
    8084};
    8185
    8286#define NTP_PORT        123
     87
     88// To stringify the NTP_PORT macro
     89#define _XSTR_(x) _STR_(x)
     90#define _STR_(x) #x
     91
    8392#define NTP_VERSION_3   3
    8493
    8594enum ntp_leap_warnings {
    status_t  
    114123ntp_update_time(const char* hostname, const char** errorString,
    115124    int32* errorCode)
    116125{
    117     hostent *server = gethostbyname(hostname);
    118 
    119     if (server == NULL) {
    120    
    121         *errorString = B_TRANSLATE("Could not contact server");
     126    int rt;
     127    struct addrinfo hints, *res;
     128
     129    memset(&hints, 0, sizeof(struct addrinfo));
     130    hints.ai_family = AF_UNSPEC;
     131    hints.ai_socktype = SOCK_DGRAM;
     132    hints.ai_protocol = 0;
     133
     134    rt = getaddrinfo(hostname, _XSTR_(NTP_PORT), &hints, &res);
     135    if (rt!=0) {
     136        *errorString = B_TRANSLATE(gai_strerror(rt));
     137        freeaddrinfo(res);
    122138        return B_ENTRY_NOT_FOUND;
    123139    }
    124140
    ntp_update_time(const char* hostname, const char** errorString,  
    137153
    138154    message.transmit_timestamp.SetTo(seconds_since_1900());
    139155
    140     int connection = socket(AF_INET, SOCK_DGRAM, 0);
    141     if (connection < 0) {
    142         *errorString = B_TRANSLATE("Could not create socket");
    143         *errorCode = errno;
    144         return B_ERROR;
    145     }
     156    int connection = 0;
    146157
    147     struct sockaddr_in address;
    148     address.sin_family = AF_INET;
    149     address.sin_port = htons(NTP_PORT);
    150     address.sin_addr.s_addr = *(uint32 *)server->h_addr_list[0];
     158    for(;res!=NULL;res=res->ai_next){
     159        connection = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
     160        if(connection == -1) continue;
    151161
    152     if (sendto(connection, (char *)&message, sizeof(ntp_data),
    153             0, (struct sockaddr *)&address, sizeof(address)) < 0) {
    154         *errorString = B_TRANSLATE("Sending request failed");
    155         *errorCode = errno;
    156         close(connection);
    157         return B_ERROR;
     162        if (sendto(connection, (char *)&message, sizeof(ntp_data),
     163            0, res->ai_addr, res->ai_addrlen) != -1) break;
     164
     165        close(connection);  // socket was created but "sendto" failed, so we close the socket before trying next address
     166    }
     167
     168    if(res==NULL){  // unable to 'connect' or 'sendto' with any of the addresses returned by getaddrinfo
     169        freeaddrinfo(res);
     170        if(connection == -1){
     171            *errorString = B_TRANSLATE("Could not create socket");
     172            *errorCode = errno;
     173            return B_ERROR;
     174        }
     175        else{
     176            *errorString = B_TRANSLATE("Sending request failed");
     177            *errorCode = errno;
     178            return B_ERROR;
     179        }
    158180    }
    159181
    160182    fd_set waitForReceived;
    ntp_update_time(const char* hostname, const char** errorString,  
    170192        *errorString = B_TRANSLATE("Waiting for answer failed");
    171193        *errorCode = errno;
    172194        close(connection);
     195        freeaddrinfo(res);
    173196        return B_ERROR;
    174197    }
    175198
    176199    message.transmit_timestamp.SetTo(0);
    177200
    178     socklen_t addressSize = sizeof(address);
    179201    if (recvfrom(connection, (char *)&message, sizeof(ntp_data), 0,
    180             (sockaddr *)&address, &addressSize) < (ssize_t)sizeof(ntp_data)) {
     202            res->ai_addr, &res->ai_addrlen) < (ssize_t)sizeof(ntp_data)){
    181203        *errorString = B_TRANSLATE("Message receiving failed");
    182204        *errorCode = errno;
    183205        close(connection);
     206        freeaddrinfo(res);
    184207        return B_ERROR;
    185208    }
    186209
    ntp_update_time(const char* hostname, const char** errorString,  
    188211
    189212    if (message.transmit_timestamp.Integer() == 0) {
    190213        *errorString = B_TRANSLATE("Received invalid time");
     214        freeaddrinfo(res);
    191215        return B_BAD_VALUE;
    192216    }
    193217
    194218    time_t now = message.transmit_timestamp.Integer() - kSecondsBetween1900And1970;
    195219    set_real_time_clock(now);
     220
     221    freeaddrinfo(res);
    196222    return B_OK;
    197223}
     224 
     225 No newline at end of file