int dns_server_new(
                Manager *m,
                DnsServer **ret,
                DnsServerType type,
                Link *l,
                int family,
                const union in_addr_union *in_addr) {

        DnsServer *s, *tail;

        assert(m);
        assert((type == DNS_SERVER_LINK) == !!l);
        assert(in_addr);

        s = new0(DnsServer, 1);
        if (!s)
                return -ENOMEM;

        s->n_ref = 1;
        s->type = type;
        s->family = family;
        s->address = *in_addr;
        s->resend_timeout = DNS_TIMEOUT_MIN_USEC;

        if (type == DNS_SERVER_LINK) {
                LIST_FIND_TAIL(servers, l->dns_servers, tail);
                LIST_INSERT_AFTER(servers, l->dns_servers, tail, s);
                s->link = l;
        } else if (type == DNS_SERVER_SYSTEM) {
                LIST_FIND_TAIL(servers, m->dns_servers, tail);
                LIST_INSERT_AFTER(servers, m->dns_servers, tail, s);
        } else if (type == DNS_SERVER_FALLBACK) {
                LIST_FIND_TAIL(servers, m->fallback_dns_servers, tail);
                LIST_INSERT_AFTER(servers, m->fallback_dns_servers, tail, s);
        } else
                assert_not_reached("Unknown server type");

        s->manager = m;

        /* A new DNS server that isn't fallback is added and the one
         * we used so far was a fallback one? Then let's try to pick
         * the new one */
        if (type != DNS_SERVER_FALLBACK &&
            m->current_dns_server &&
            m->current_dns_server->type == DNS_SERVER_FALLBACK)
                manager_set_dns_server(m, NULL);

        if (ret)
                *ret = s;

        return 0;
}
int server_name_new(
                Manager *m,
                ServerName **ret,
                ServerType type,
                const char *string) {

        ServerName *n, *tail;

        assert(m);
        assert(string);

        n = new0(ServerName, 1);
        if (!n)
                return -ENOMEM;

        n->type = type;
        n->string = strdup(string);
        if (!n->string) {
                free(n);
                return -ENOMEM;
        }

        if (type == SERVER_SYSTEM) {
                LIST_FIND_TAIL(names, m->system_servers, tail);
                LIST_INSERT_AFTER(names, m->system_servers, tail, n);
        } else if (type == SERVER_LINK) {
                LIST_FIND_TAIL(names, m->link_servers, tail);
                LIST_INSERT_AFTER(names, m->link_servers, tail, n);
        } else if (type == SERVER_FALLBACK) {
                LIST_FIND_TAIL(names, m->fallback_servers, tail);
                LIST_INSERT_AFTER(names, m->fallback_servers, tail, n);
        } else
                assert_not_reached("Unknown server type");

        n->manager = m;

        if (type != SERVER_FALLBACK &&
            m->current_server_name &&
            m->current_server_name->type == SERVER_FALLBACK)
                manager_set_server_name(m, NULL);

        log_debug("Added new server %s.", string);

        if (ret)
                *ret = n;

        return 0;
}
int server_address_new(
                ServerName *n,
                ServerAddress **ret,
                const union sockaddr_union *sockaddr,
                socklen_t socklen) {

        ServerAddress *a, *tail;

        assert(n);
        assert(sockaddr);
        assert(socklen >= offsetof(struct sockaddr, sa_data));
        assert(socklen <= sizeof(union sockaddr_union));

        a = new0(ServerAddress, 1);
        if (!a)
                return -ENOMEM;

        memcpy(&a->sockaddr, sockaddr, socklen);
        a->socklen = socklen;

        LIST_FIND_TAIL(addresses, n->addresses, tail);
        LIST_INSERT_AFTER(addresses, n->addresses, tail, a);
        a->name = n;

        if (ret)
                *ret = a;

        return 0;
}
Exemple #4
0
void dns_server_move_back_and_unmark(DnsServer *s) {
        DnsServer *tail;

        assert(s);

        if (!s->marked)
                return;

        s->marked = false;

        if (!s->linked || !s->servers_next)
                return;

        /* Move us to the end of the list, so that the order is
         * strictly kept, if we are not at the end anyway. */

        switch (s->type) {

        case DNS_SERVER_LINK:
                assert(s->link);
                LIST_FIND_TAIL(servers, s, tail);
                LIST_REMOVE(servers, s->link->dns_servers, s);
                LIST_INSERT_AFTER(servers, s->link->dns_servers, tail, s);
                break;

        case DNS_SERVER_SYSTEM:
                LIST_FIND_TAIL(servers, s, tail);
                LIST_REMOVE(servers, s->manager->dns_servers, s);
                LIST_INSERT_AFTER(servers, s->manager->dns_servers, tail, s);
                break;

        case DNS_SERVER_FALLBACK:
                LIST_FIND_TAIL(servers, s, tail);
                LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
                LIST_INSERT_AFTER(servers, s->manager->fallback_dns_servers, tail, s);
                break;

        default:
                assert_not_reached("Unknown server type");
        }
}