InstallStatus install_listener(const std::string& local_name, const char* connect_to,
                               atransport* transport, int no_rebind, int* resolved_tcp_port,
                               std::string* error) {
    for (auto& l : listener_list) {
        if (local_name == l->local_name) {
            // Can't repurpose a smartsocket.
            if(l->connect_to[0] == '*') {
                *error = "cannot repurpose smartsocket";
                return INSTALL_STATUS_INTERNAL_ERROR;
            }

            // Can't repurpose a listener if 'no_rebind' is true.
            if (no_rebind) {
                *error = "cannot rebind";
                return INSTALL_STATUS_CANNOT_REBIND;
            }

            l->connect_to = connect_to;
            if (l->transport != transport) {
                l->transport->RemoveDisconnect(&l->disconnect);
                l->transport = transport;
                l->transport->AddDisconnect(&l->disconnect);
            }
            return INSTALL_STATUS_OK;
        }
    }

    std::unique_ptr<alistener> listener(new alistener(local_name, connect_to));

    listener->fd = local_name_to_fd(listener.get(), resolved_tcp_port, error);
    if (listener->fd < 0) {
        return INSTALL_STATUS_CANNOT_BIND;
    }

    close_on_exec(listener->fd);
    if (listener->connect_to == "*smartsocket*") {
        fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get());
    } else {
        fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get());
    }
    fdevent_set(&listener->fde, FDE_READ);

    listener->transport = transport;

    if (transport) {
        listener->disconnect.opaque = listener.get();
        listener->disconnect.func   = listener_disconnect;
        transport->AddDisconnect(&listener->disconnect);
    }

    listener_list.push_back(std::move(listener));
    return INSTALL_STATUS_OK;
}
Esempio n. 2
0
static int install_listener(const char *local_name, const char *connect_to, atransport* transport)
{
    alistener *l;

    //printf("install_listener('%s','%s')\n", local_name, connect_to);

    for(l = listener_list.next; l != &listener_list; l = l->next){
        if(strcmp(local_name, l->local_name) == 0) {
            char *cto;

                /* can't repurpose a smartsocket */
            if(l->connect_to[0] == '*') {
                return -1;
            }

            cto = strdup(connect_to);
            if(cto == 0) {
                return -1;
            }

            //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
            free((void*) l->connect_to);
            l->connect_to = cto;
            if (l->transport != transport) {
                remove_transport_disconnect(l->transport, &l->disconnect);
                l->transport = transport;
                add_transport_disconnect(l->transport, &l->disconnect);
            }
            return 0;
        }
    }

    if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
    if((l->local_name = strdup(local_name)) == 0) goto nomem;
    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;


    l->fd = local_name_to_fd(local_name);
    if(l->fd < 0) {
        free((void*) l->local_name);
        free((void*) l->connect_to);
        free(l);
        printf("cannot bind '%s'\n", local_name);
        return -2;
    }

    close_on_exec(l->fd);
    if(!strcmp(l->connect_to, "*smartsocket*")) {
        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
    } else {
        fdevent_install(&l->fde, l->fd, listener_event_func, l);
    }
    fdevent_set(&l->fde, FDE_READ);

    l->next = &listener_list;
    l->prev = listener_list.prev;
    l->next->prev = l;
    l->prev->next = l;
    l->transport = transport;

    if (transport) {
        l->disconnect.opaque = l;
        l->disconnect.func   = listener_disconnect;
        add_transport_disconnect(transport, &l->disconnect);
    }
    return 0;

nomem:
    fatal("cannot allocate listener");
    return 0;
}
Esempio n. 3
0
static install_status_t install_listener(const char *local_name,
                                         const char *connect_to,
                                         atransport* transport,
                                         int no_rebind)
{
    alistener *l;

    D("install_listener('%s','%s')\n", local_name, connect_to);

    for(l = listener_list.next; l != &listener_list; l = l->next){
        if(strcmp(local_name, l->local_name) == 0) {
            char *cto;

                /* can't repurpose a smartsocket */
            if(l->connect_to[0] == '*') {
                return INSTALL_STATUS_INTERNAL_ERROR;
            }

                /* can't repurpose a listener if 'no_rebind' is true */
            if (no_rebind) {
                return INSTALL_STATUS_CANNOT_REBIND;
            }

            cto = strdup(connect_to);
            if(cto == 0) {
                return INSTALL_STATUS_INTERNAL_ERROR;
            }

            D("rebinding '%s' to '%s'\n", local_name, connect_to);
            free((void*) l->connect_to);
            l->connect_to = cto;
            if (l->transport != transport) {
                remove_transport_disconnect(l->transport, &l->disconnect);
                l->transport = transport;
                add_transport_disconnect(l->transport, &l->disconnect);
            }
            return INSTALL_STATUS_OK;
        }
    }

    if((l = (alistener*)calloc(1, sizeof(alistener))) == 0) goto nomem;
    if((l->local_name = strdup(local_name)) == 0) goto nomem;
    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;

    D("LOCAL NAME: %s\n", local_name);

    l->fd = local_name_to_fd(local_name);
    D("l->fd: %d\n", l->fd);
    if(l->fd < 0) {
        free((void*) l->local_name);
        free((void*) l->connect_to);
        free(l);
        D("cannot bind '%s'\n", local_name);
        return INSTALL_STATUS_CANNOT_BIND;
    }

    close_on_exec(l->fd);
    if(!strcmp(l->connect_to, "*smartsocket*")) {
        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
    } else {
        fdevent_install(&l->fde, l->fd, listener_event_func, l);
    }
    fdevent_set(&l->fde, FDE_READ);

    l->next = &listener_list;
    l->prev = listener_list.prev;
    l->next->prev = l;
    l->prev->next = l;
    l->transport = transport;

    if (transport) {
        l->disconnect.opaque = l;
        l->disconnect.func   = listener_disconnect;
        add_transport_disconnect(transport, &l->disconnect);
    }
    return INSTALL_STATUS_OK;

nomem:
    fatal("cannot allocate listener");
    return INSTALL_STATUS_INTERNAL_ERROR;
}
install_status_t install_listener(const char *local_name,
                                  const char *connect_to,
                                  atransport* transport,
                                  int no_rebind)
{
    for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
        if (strcmp(local_name, l->local_name) == 0) {
            char* cto;

            /* can't repurpose a smartsocket */
            if(l->connect_to[0] == '*') {
                return INSTALL_STATUS_INTERNAL_ERROR;
            }

            /* can't repurpose a listener if 'no_rebind' is true */
            if (no_rebind) {
                return INSTALL_STATUS_CANNOT_REBIND;
            }

            cto = strdup(connect_to);
            if(cto == 0) {
                return INSTALL_STATUS_INTERNAL_ERROR;
            }

            free((void*) l->connect_to);
            l->connect_to = cto;
            if (l->transport != transport) {
                remove_transport_disconnect(l->transport, &l->disconnect);
                l->transport = transport;
                add_transport_disconnect(l->transport, &l->disconnect);
            }
            return INSTALL_STATUS_OK;
        }
    }

    alistener* listener = reinterpret_cast<alistener*>(
                              calloc(1, sizeof(alistener)));
    if (listener == nullptr) {
        goto nomem;
    }

    listener->local_name = strdup(local_name);
    if (listener->local_name == nullptr) {
        goto nomem;
    }

    listener->connect_to = strdup(connect_to);
    if (listener->connect_to == nullptr) {
        goto nomem;
    }

    listener->fd = local_name_to_fd(local_name);
    if (listener->fd < 0) {
        free(listener->local_name);
        free(listener->connect_to);
        free(listener);
        printf("cannot bind '%s'\n", local_name);
        return INSTALL_STATUS_CANNOT_BIND;
    }

    close_on_exec(listener->fd);
    if (!strcmp(listener->connect_to, "*smartsocket*")) {
        fdevent_install(&listener->fde, listener->fd, ss_listener_event_func,
                        listener);
    } else {
        fdevent_install(&listener->fde, listener->fd, listener_event_func,
                        listener);
    }
    fdevent_set(&listener->fde, FDE_READ);

    listener->next = &listener_list;
    listener->prev = listener_list.prev;
    listener->next->prev = listener;
    listener->prev->next = listener;
    listener->transport = transport;

    if (transport) {
        listener->disconnect.opaque = listener;
        listener->disconnect.func   = listener_disconnect;
        add_transport_disconnect(transport, &listener->disconnect);
    }
    return INSTALL_STATUS_OK;

nomem:
    fatal("cannot allocate listener");
    return INSTALL_STATUS_INTERNAL_ERROR;
}