Linux névfeloldás (getaddrinfo) érdekesség

Szóval, van egy domain név, jelenleg 3 IPv4 van mögötte (3 szerver). Célja, a DNS alapú load balance.

Már korábban előjött a probléma más kapcsán, csak akkor nem mentem a végére. Akkor az is szóba jött, hogy alkalmazás-specifikus is lehet a dolog, mivel ha pl. pinggel nézem a domaint bárhonnan, akkor jó, tehát kb. véletlen szerűen pingelte az 3 ip-ből az egyiket.

De most újra előjött, csináltam egy egyszerű C programot, ami a getaddrinfo-val lekérdezi a domainhez tartozó címeket, amit aztán kiír sorba, ahogy megkapja a láncolt listában és ennyi. Ha azon a 3 gép valamelyikén nézem, amelyikre mutat a domain, akkor MINDIG a saját ip címe lesz az első, ha a fejem tetejére állok is. (A második-harmadik ip sorrendje már változik). Mindenhonnan máshonnan nézve megy úgy, ahogy a DNS-től elvárod.

Ez miért van, minek a hozadéka/következménye?

Hozzászólások

RTFM?

Normally, the application should try using the addresses in the order in which they are returned.  The sorting function used within getaddrinfo() is defined in RFC 3484; the order can be tweaked for a particular system by editing /etc/gai.conf (available since glibc 2.5).

 

De mi a baj? Hogy nem random? Sosem volt az. Max a sok szakerto, aki irkal rola es okitja a nepet megsem annyra szakerto.

Ha nem tetszik az alap szabalyrendszer, akkor kliens oldalon kezeld a neked tetszo modon.

// random: Dobj fel egy ermet 100x es nezd meg, hogy milyen hosszu fej vagy iras sorozatok lesznek. Aztan gondold at, hogy jo-e neked igy egy LB megoldas.

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>

int main(int argc, char **argv)
{

    if (argc<2) {
        printf("Not enough parameter\n");
        return -1;
    }

    struct addrinfo *pai = NULL;
    struct addrinfo hints;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0;
    hints.ai_protocol = 0;

    int err = getaddrinfo(argv[1], NULL, &hints, &pai);
    
    if (err != 0) {
        fprintf(stderr, "Error in getaddrinfo: %s\n", gai_strerror(err));
        return -1;
    }

    while(pai) {

        if (pai->ai_family == AF_INET) {
            struct sockaddr_in *psai = (struct sockaddr_in*)pai->ai_addr;
            char ip[INET_ADDRSTRLEN];
            if (inet_ntop(pai->ai_family, &(psai->sin_addr), ip, INET_ADDRSTRLEN) != NULL) {
                printf("IP: %s\n", ip);
            }
        } else if (pai->ai_family == AF_INET6) {
            struct sockaddr_in6 *psai = (struct sockaddr_in6*)pai->ai_addr;
            char ip[INET6_ADDRSTRLEN];
            if (inet_ntop(pai->ai_family, &(psai->sin6_addr), ip, INET6_ADDRSTRLEN) != NULL) {
                printf("IP6: %s\n", ip);
            }
        } else {
            printf("Don't know how to convert family %d addresses\n", pai->ai_family);
        }

        pai=pai->ai_next;

    }
    
    freeaddrinfo(pai);
    
    printf("\nDone.\n\n");
    
    return 0;
}

"Sose a gép a hülye."