Caching of DNS entries is done better by a local caching DNS or by libc.
database.c database.h \
eventl.c eventl.h \
facet_limit.c facet_limit.h \
- getaddrinfo.c \
host.h \
http.c http.h http_command.c \
incref.c incref.h \
struct connection *co = client_get_connection(cl);
ZOOM_connection link = connection_get_link(co);
ZOOM_resultset rs;
- char *databaseName = sdb->database->databases[0];
const char *opt_piggyback = session_setting_oneval(sdb, PZ_PIGGYBACK);
const char *opt_queryenc = session_setting_oneval(sdb, PZ_QUERYENCODING);
const char *opt_elements = session_setting_oneval(sdb, PZ_ELEMENTS);
sprintf(startrecs_str, "%d", cl->startrecs);
ZOOM_connection_option_set(link, "start", startrecs_str);
- if (databaseName)
- ZOOM_connection_option_set(link, "databaseName", databaseName);
-
/* TODO Verify does it break something for CQL targets(non-SOLR) ? */
/* facets definition is in PQF */
client_set_facets_request(cl, link);
co->state = Conn_Resolving;
co->operation_timeout = operation_timeout;
co->session_timeout = session_timeout;
- if (host->ipport)
- connection_connect(co, iochan_man);
+
+ connection_connect(co, iochan_man);
yaz_mutex_enter(host->mutex);
co->next = co->host->connections;
co->client = 0;
}
-void connect_resolver_host(struct host *host, iochan_man_t iochan_man)
-{
- struct connection *con;
-
-start:
- yaz_mutex_enter(host->mutex);
- con = host->connections;
- while (con)
- {
- if (con->state == Conn_Resolving)
- {
- if (!host->ipport) /* unresolved */
- {
- remove_connection_from_host(con);
- yaz_mutex_leave(host->mutex);
- connection_destroy(con);
- goto start;
- /* start all over .. at some point it will be NULL */
- }
- else if (!con->client)
- {
- remove_connection_from_host(con);
- yaz_mutex_leave(host->mutex);
- connection_destroy(con);
- /* start all over .. at some point it will be NULL */
- goto start;
- }
- else
- {
- yaz_mutex_leave(host->mutex);
- connection_connect(con, iochan_man);
- client_start_search(con->client);
- goto start;
- }
- }
- else
- {
- yaz_log(YLOG_LOG, "connect_resolver_host: state=%d", con->state);
- con = con->next;
- }
- }
- yaz_mutex_leave(host->mutex);
-}
-
static struct host *connection_get_host(struct connection *con)
{
return con->host;
const char *zproxy = session_setting_oneval(sdb, PZ_ZPROXY);
const char *apdulog = session_setting_oneval(sdb, PZ_APDULOG);
- assert(host->ipport);
assert(con);
ZOOM_options_set(zoptions, "async", "1");
strcat(http_hostport, host->hostport);
ZOOM_connection_connect(link, http_hostport, 0);
}
- else if (zproxy && *zproxy)
- ZOOM_connection_connect(link, host->hostport, 0);
else
- ZOOM_connection_connect(link, host->ipport, 0);
+ {
+ ZOOM_connection_connect(link, host->hostport, 0);
+ }
con->link = link;
con->iochan = iochan_create(-1, connection_handler, 0, "connection_socket");
struct database_criterion *next;
};
-
struct database_hosts {
struct host *hosts;
YAZ_MUTEX mutex;
};
// Create a new host structure for hostport
-static struct host *create_host(const char *hostport, iochan_man_t iochan_man)
+static struct host *create_host(const char *hostport)
{
struct host *host;
+ char *db_comment;
host = xmalloc(sizeof(struct host));
host->hostport = xstrdup(hostport);
+ db_comment = strchr(host->hostport, '#');
+ if (db_comment)
+ *db_comment = '\0';
host->connections = 0;
- host->ipport = 0;
host->mutex = 0;
- if (host_getaddrinfo(host, iochan_man))
- {
- xfree(host->hostport);
- xfree(host);
- return 0;
- }
pazpar2_mutex_create(&host->mutex, "host");
yaz_cond_create(&host->cond_ready);
}
static struct host *find_host(database_hosts_t hosts,
- const char *hostport, iochan_man_t iochan_man)
+ const char *hostport)
{
struct host *p;
yaz_mutex_enter(hosts->mutex);
break;
if (!p)
{
- p = create_host(hostport, iochan_man);
+ p = create_host(hostport);
if (p)
{
p->next = hosts->hosts;
if (db->host == 0)
{
struct host *host;
- char *p;
- char hostport[256];
- strcpy(hostport, db->url);
- if ((p = strchr(hostport, '/')))
- *p = '\0';
- if (!(host = find_host(service->server->database_hosts,
- hostport, service->server->iochan_man)))
+ if (!(host = find_host(service->server->database_hosts, db->url)))
return -1;
db->host = host;
}
struct database *new_database(const char *id, NMEM nmem)
{
struct database *db;
- char hostport[256];
- char *dbname;
- char *db_comment;
struct setting *idset;
- if (strlen(id) > 255)
- return 0;
- strcpy(hostport, id);
- if ((dbname = strchr(hostport, '/')))
- *(dbname++) = '\0';
- else
- dbname = "";
- db_comment = strchr(dbname, '#');
- if (db_comment)
- *db_comment = '\0';
db = nmem_malloc(nmem, sizeof(*db));
memset(db, 0, sizeof(*db));
- db->host = 0;
+
db->url = nmem_strdup(nmem, id);
- db->databases = nmem_malloc(nmem, 2 * sizeof(char *));
- db->databases[0] = nmem_strdup(nmem, dbname);
- db->databases[1] = 0;
db->errors = 0;
- db->explain = 0;
+ db->host = 0;
db->num_settings = PZ_MAX_EOF;
db->settings = nmem_malloc(nmem, sizeof(struct settings*) *
struct conf_service *service)
{
struct database *db;
- struct zr_explain *explain = 0;
db = new_database(id, service->nmem);
- db->explain = explain;
+
db->next = service->databases;
service->databases = db;
// Cycles through databases, calling a handler function on the ones for
// which all criteria matched.
int session_grep_databases(struct session *se, const char *filter,
- void (*fun)(void *context, struct session_database *db))
+ void (*fun)(struct session *se, struct session_database *db))
{
struct session_database *p;
NMEM nmem = nmem_create();
struct host *p_next = p->next;
yaz_mutex_destroy(&p->mutex);
yaz_cond_destroy(&p->cond_ready);
- xfree(p->ipport);
xfree(p->hostport);
xfree(p);
p = p_next;
struct conf_service;
struct database *find_database(const char *id, struct conf_service *service);
int session_grep_databases(struct session *se, const char *filter,
- void (*fun)(void *context, struct session_database *db));
+ void (*fun)(struct session *se, struct session_database *db));
int predef_grep_databases(void *context, struct conf_service *service,
void (*fun)(void *context, struct database *db));
int match_zurl(const char *zurl, const char *pattern);
database_hosts_t database_hosts_create(void);
void database_hosts_destroy(database_hosts_t *);
+
#endif
+++ /dev/null
-/* This file is part of Pazpar2.
- Copyright (C) 2006-2011 Index Data
-
-Pazpar2 is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-*/
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "sel_thread.h"
-
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <stdlib.h>
-
-#include <assert.h>
-#include <sys/types.h>
-#if HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef WIN32
-#include <winsock.h>
-#endif
-#if HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#include <yaz/log.h>
-#include <yaz/nmem.h>
-#include <yaz/tcpip.h>
-
-#include "session.h"
-#include "connection.h"
-#include "host.h"
-
-/* Only use a threaded resolver on Unix that offers getaddrinfo.
- gethostbyname is NOT reentrant.
- */
-#if HAVE_GETADDRINFO
-#ifndef WIN32
-#define USE_THREADED_RESOLVER 1
-#endif
-#endif
-
-struct work {
- char *hostport; /* hostport to be resolved in separate thread */
- char *ipport; /* result or NULL if it could not be resolved */
- struct host *host; /* host that we're dealing with - mother thread */
- iochan_man_t iochan_man; /* iochan manager */
-};
-
-static int log_level = YLOG_LOG;
-
-void perform_getaddrinfo(struct work *w)
-{
- int res = 0;
- char *port;
-#if HAVE_GETADDRINFO
- struct addrinfo *addrinfo, hints;
-#else
- struct hostent *hp;
-#endif
- char *hostport = xstrdup(w->hostport);
-
- if ((port = strchr(hostport, ':')))
- *(port++) = '\0';
- else
- port = "210";
-
-#if HAVE_GETADDRINFO
- hints.ai_flags = 0;
- hints.ai_family = PF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_addrlen = 0;
- hints.ai_addr = 0;
- hints.ai_canonname = 0;
- hints.ai_next = 0;
- // This is not robust code. It assumes that getaddrinfo always
- // returns AF_INET address.
- if ((res = getaddrinfo(hostport, port, &hints, &addrinfo)))
- {
- yaz_log(YLOG_WARN, "Failed to resolve %s: %s",
- w->hostport, gai_strerror(res));
- }
- else
- {
- char ipport[128];
- unsigned char addrbuf[4];
- assert(addrinfo->ai_family == PF_INET);
- memcpy(addrbuf,
- &((struct sockaddr_in*)addrinfo->ai_addr)->sin_addr.s_addr, 4);
- sprintf(ipport, "%u.%u.%u.%u:%s",
- addrbuf[0], addrbuf[1], addrbuf[2], addrbuf[3], port);
- freeaddrinfo(addrinfo);
- w->ipport = xstrdup(ipport);
- yaz_log(log_level, "Resolved %s -> %s", hostport, ipport);
- }
-#else
- hp = gethostbyname(hostport);
- if (!hp)
- {
- yaz_log(YLOG_WARN|YLOG_ERRNO, "Failed to resolve %s", hostport);
- }
- else
- {
- char ipport[128];
- unsigned char addrbuf[4];
-
- memcpy(addrbuf, *hp->h_addr_list, 4 * sizeof(unsigned char));
- sprintf(ipport, "%u.%u.%u.%u:%s",
- addrbuf[0], addrbuf[1], addrbuf[2], addrbuf[3], port);
- w->ipport = xstrdup(ipport);
- yaz_log(log_level, "Resolved %s -> %s", hostport, ipport);
- }
-#endif
- xfree(hostport);
-}
-
-static void work_handler(void *vp)
-{
- struct work *w = vp;
-
- int sec = 0; /* >0 for debugging/testing purposes */
- if (sec)
- {
- yaz_log(log_level, "waiting %d seconds", sec);
-#if HAVE_UNISTD_H
- sleep(sec);
-#endif
- }
- perform_getaddrinfo(w);
-}
-
-#if USE_THREADED_RESOLVER
-void iochan_handler(struct iochan *i, int event)
-{
- sel_thread_t p = iochan_getdata(i);
-
- if (event & EVENT_INPUT)
- {
- struct work *w = sel_thread_result(p);
- w->host->ipport = w->ipport;
- connect_resolver_host(w->host, w->iochan_man);
- xfree(w);
- }
-}
-
-static sel_thread_t resolver_thread = 0;
-
-static void getaddrinfo_start(iochan_man_t iochan_man)
-{
- int fd;
- sel_thread_t p = resolver_thread =
- sel_thread_create(work_handler, 0 /* work_destroy */, &fd,
- 3 /* no of resolver threads */);
- if (!p)
- {
- yaz_log(YLOG_FATAL|YLOG_ERRNO, "sel_create_create failed");
- exit(1);
- }
- else
- {
- IOCHAN chan = iochan_create(fd, iochan_handler, EVENT_INPUT,
- "getaddrinfo_socket");
- iochan_setdata(chan, p);
- iochan_add(iochan_man, chan);
- }
- yaz_log(log_level, "resolver start");
- resolver_thread = p;
-}
-#endif
-
-int host_getaddrinfo(struct host *host, iochan_man_t iochan_man)
-{
- struct work *w = xmalloc(sizeof(*w));
- int use_thread = 0; /* =0 to disable threading entirely */
-
- w->hostport = host->hostport;
- w->ipport = 0;
- w->host = host;
- w->iochan_man = iochan_man;
-#if USE_THREADED_RESOLVER
- if (use_thread)
- {
- if (resolver_thread == 0)
- getaddrinfo_start(iochan_man);
- assert(resolver_thread);
- sel_thread_add(resolver_thread, w);
- return 0;
- }
-#endif
- perform_getaddrinfo(w);
- host->ipport = w->ipport;
- xfree(w);
- if (!host->ipport)
- return -1;
- return 0;
-}
-
-/*
- * Local variables:
- * c-basic-offset: 4
- * c-file-style: "Stroustrup"
- * indent-tabs-mode: nil
- * End:
- * vim: shiftwidth=4 tabstop=8 expandtab
- */
-
/** \brief Represents a host (irrespective of databases) */
struct host {
char *hostport;
- char *ipport;
struct connection *connections; // All connections to this
struct host *next;
YAZ_MUTEX mutex;
server->charsets = 0;
server->http_server = 0;
server->iochan_man = 0;
- server->database_hosts = 0;
+ server->database_hosts = config->database_hosts;
server->settings_fname = 0;
if (server_id)
config->servers = 0;
config->no_threads = 0;
config->iochan_man = 0;
- config->database_hosts = 0;
+ config->database_hosts = database_hosts_create();
config->confdir = wrbuf_alloc();
if ((p = strrchr(fname,
struct conf_server *s_next = server->next;
server_destroy(server);
server = s_next;
+ database_hosts_destroy(&config->database_hosts);
}
- database_hosts_destroy(&config->database_hosts);
-
wrbuf_destroy(config->confdir);
nmem_destroy(config->nmem);
}
{
struct conf_server *ser;
- conf->database_hosts = database_hosts_create();
for (ser = conf->servers; ser; ser = ser->next)
{
struct conf_service *s = ser->service;
- ser->database_hosts = conf->database_hosts;
-
for (;s ; s = s->next)
{
resolve_databases(s);
}
http_mutex_init(ser);
}
- iochan_man_events(conf->iochan_man);
+ iochan_man_events(conf->iochan_man);
}
int config_start_listeners(struct conf_config *conf,
}
//callback for grep_databases
-static void select_targets_callback(void *context, struct session_database *db)
+static void select_targets_callback(struct session *se,
+ struct session_database *db)
{
- struct session *se = (struct session*) context;
struct client *cl = client_create();
struct client_list *l;
client_set_database(cl, db);
struct database {
struct host *host;
char *url;
- char **databases;
int errors;
- struct zr_explain *explain;
int num_settings;
struct setting **settings;
struct database *next;
"$(OBJDIR)\normalize7bit.obj" \
"$(OBJDIR)\database.obj" \
"$(OBJDIR)\settings.obj" \
- "$(OBJDIR)\getaddrinfo.obj" \
"$(OBJDIR)\charsets.obj" \
"$(OBJDIR)\client.obj" \
"$(OBJDIR)\jenkins_hash.obj" \