Commit f8c95599 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(dump_connections): Include a flag that tells if the session has

	completed the handshake or not.
(dns_resolution): New function.
(get_host_name): Removed.
(login_request): Reorganized the code to use the new
	callback-driven API of ISC host lookups.
(handle_accept_event): Call set_time(), so that the connect_time
	is set correctly.
parent 7c31ea52
/*
* $Id: connections.c,v 0.114 2003/08/04 06:54:26 ceder Exp $
* $Id: connections.c,v 0.115 2003/08/05 09:51:36 ceder Exp $
* Copyright (C) 1991-2002 Lysator Academic Computer Association.
*
* This file is part of the LysKOM server.
......@@ -47,6 +47,7 @@
#include <sys/socket.h>
#include <signal.h>
#include <assert.h>
#include <netdb.h>
#include "oop.h"
......@@ -84,6 +85,7 @@
#include "text-garb.h"
#include "timeval-util.h"
#include "stats.h"
#include "string-malloc.h"
oop_source_sys * kom_server_oop_src = NULL;
struct isc_mcb * kom_server_mcb = NULL;
......@@ -593,7 +595,8 @@ dump_connections(void)
for (s = 0; (s = traverse_connections(s)) != 0;)
{
conn = get_conn_by_number(s);
fprintf(fp, "%d %lu %s\n", conn->isc_session->fd, conn->session_no,
fprintf(fp, "%d %lu %d %s\n", conn->isc_session->fd, conn->session_no,
handshake_ok(conn, 0),
conn->peer);
}
......@@ -671,48 +674,74 @@ check_kill_flg(oop_source *UNUSED(source),
return OOP_CONTINUE;
}
static char *
get_host_name(union isc_address *addr)
static void *
dns_resolution(struct isc_scb *scb,
enum isc_resolve_status res,
long errcode)
{
char *res = NULL;
char *hostname = NULL;
struct timeval before;
struct timeval after;
double diff = -1.0;
Connection *conn;
char *hostname = NULL;
if (param.use_dns)
{
if (gettimeofday(&before, NULL) < 0)
kom_log("gettimeofday failed: %s\n", strerror(errno));
update_stat(STAT_DNS_QUEUE, 1);
res = hostname = isc_gethostname(addr, NULL, 0);
update_stat(STAT_DNS_QUEUE, -1);
update_stat(STAT_DNS_QUEUE, -1);
conn = scb->udg;
if (gettimeofday(&after, NULL) < 0)
kom_log("gettimeofday failed: %s\n", strerror(errno));
conn->dns_done = TRUE;
if (conn->blocked_by_dns)
{
if (isc_enable(scb) < 0)
restart_kom("Failed to enble session after DNS resolution.\n");
diff = (after.tv_sec - before.tv_sec
+ 1e-6 * (after.tv_usec - before.tv_usec));
conn->blocked_by_dns = FALSE;
}
if (res == NULL)
res = isc_getipnum(addr, NULL, 0);
if (res == isc_resolve_aborted)
return OOP_CONTINUE;
if (gettimeofday(&after, NULL) < 0)
kom_log("gettimeofday failed: %s\n", strerror(errno));
diff = timeval_diff_d(after, conn->connect_time);
if (param.use_dns && diff > param.dns_log_threshold)
if (res == isc_resolve_h_errno)
{
if (hostname == NULL)
kom_log("Slow bad DNS: %s failed after %f seconds\n", res, diff);
hostname = s_crea_c_str(scb->remote);
if (errcode == HOST_NOT_FOUND)
kom_log("No hostname found for %s.\n", hostname);
else if (errcode == TRY_AGAIN)
kom_log("Lookup of %s timed out.\n", hostname);
else if (errcode == NO_RECOVERY)
kom_log("Non-recoverable error looking up %s.\n", hostname);
else if (errcode == NO_ADDRESS)
kom_log("Got NO_ADDRESS error looking up %s.\n", hostname);
else
kom_log("Slow DNS: got %s after %f seconds\n", res, diff);
kom_log("Unknown resolver error %ld looking up %s.\n",
errcode, hostname);
}
return res;
if (diff > param.dns_log_threshold)
{
if (hostname == NULL)
hostname = s_crea_c_str(scb->remote);
if (res == isc_resolve_ok)
kom_log("Slow DNS: got %s after %f seconds\n", hostname, diff);
else
kom_log("Slow bad DNS: %s failed after %f seconds\n",
hostname, diff);
}
if (hostname != NULL)
string_free(hostname);
return OOP_CONTINUE;
}
static void
write_err_cb(struct isc_scb *cb_session,
int saved_errno)
......@@ -753,11 +782,9 @@ login_request(struct isc_scb *session)
{
Connection * cp;
const char *realuser;
char *hostname = NULL;
char peername[256];
char portbuf[1+2+3*sizeof(long)];
size_t hostlen;
size_t portlen;
char *remote_ip = NULL;
/* Supress logins if /etc/nologin exists */
if (fexists(param.nologin_file))
......@@ -768,65 +795,64 @@ login_request(struct isc_scb *session)
return;
}
hostname = get_host_name(session->raddr);
if (hostname == NULL)
kom_log("WNG: login_request(): unknown hostid.\n");
/* Get the real user name, as returned by the Ident protocol (rfc 931). */
realuser = get_real_username(session, hostname);
if (realuser == NULL && param.authentication_level == 2)
{
kom_log("Connection from %s rejected - no IDENT available.\n",
hostname);
isc_puts("%% No IDENT server reachable at your site.\n",
session);
isc_flush(session);
isc_destroy(kom_server_mcb, session);
return;
}
/* Create a Connection, and link the Connection and the
isc_session together. */
cp = new_client();
cp->isc_session = session;
session->udg = cp;
update_stat(STAT_CLIENTS, 1);
/* Start with max penalty, so that it doesn't pay to make a lot of
new connections. */
cp->penalty = param.max_penalty;
cp->penalty_generation = penalty_generation;
/* Store the IP address in readable form. */
s_crea_str(&cp->remote_ip, isc_getipnum(session->raddr, NULL, 0));
remote_ip = s_crea_c_str(cp->remote_ip);
if (hostname == NULL)
s_crea_str(&cp->hostname, "unknown");
/* Initiate DNS lookup. */
if (param.use_dns)
{
update_stat(STAT_DNS_QUEUE, 1);
isc_resolve_remote(session, dns_resolution);
}
else
s_crea_str(&cp->hostname, hostname);
s_strcpy(&session->remote, cp->remote_ip);
if (realuser != NULL)
s_crea_str(&cp->ident_user, realuser);
/* Update the status file that contains all connection. */
sprintf(portbuf, " %d", isc_getportnum(session->raddr));
portlen = strlen(portbuf);
cp->peer = smalloc(s_strlen(cp->remote_ip) + portlen + 1);
strcpy(cp->peer, remote_ip);
strcpy(cp->peer + s_strlen(cp->remote_ip), portbuf);
BUG(("\n[Client %lu from %s is connecting]\n", cp->session_no, hostname));
dump_connections();
/* Start with max penalty, so that it doesn't pay to make a lot of
new connections. */
cp->penalty = param.max_penalty;
cp->penalty_generation = penalty_generation;
isc_getipnum(session->raddr, peername, sizeof(peername));
hostlen = strlen(peername);
if (hostlen >= sizeof(peername)-1)
/* Get the real user name, as returned by the Ident protocol (rfc 931). */
realuser = get_real_username(session, remote_ip);
if (realuser == NULL && param.authentication_level == 2)
{
kom_log("login_request(): truncated remote peer address %s.\n",
peername);
kom_log("Connection from %s rejected - no IDENT available.\n",
remote_ip);
isc_puts("%% No IDENT server reachable at your site.\n",
session);
isc_flush(session);
logout_client(cp);
string_free(remote_ip);
return;
}
sprintf(portbuf, " %d", isc_getportnum(session->raddr));
portlen = strlen(portbuf);
cp->peer = smalloc(hostlen + portlen + 1);
strcpy(cp->peer, peername);
strcpy(cp->peer + hostlen, portbuf);
update_stat(STAT_CLIENTS, 1);
dump_connections();
if (realuser != NULL)
s_crea_str(&cp->ident_user, realuser);
BUG(("\n[Client %lu from %s is connecting]\n", cp->session_no, remote_ip));
isc_set_read_callback(session, data_available_callback, write_err_cb,
stale_cb, idle_cb);
string_free(remote_ip);
}
static void
......@@ -1041,6 +1067,8 @@ handle_accept_event(struct isc_scb *UNUSED(accepting_session),
{
new_session->udg = NULL;
set_time();
if (new_session->fd <= PROTECTED_FDS || new_session->fd >= fd_ceiling)
{
BUG(("Connection attempt rejected.\n"));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment