Пример #1
0
static void
authDigestUserLinkNonce(auth_user_t * auth_user, digest_nonce_h * nonce)
{
    dlink_node *node;
    digest_user_h *digest_user;
    if (!auth_user || !nonce)
	return;
    if (!auth_user->scheme_data)
	return;
    digest_user = auth_user->scheme_data;
    node = digest_user->nonces.head;
    while (node && (node->data != nonce))
	node = node->next;
    if (node)
	return;
    node = dlinkNodeNew();
    dlinkAddTail(nonce, node, &digest_user->nonces);
    authDigestNonceLink(nonce);
    /* ping this nonce to this auth user */
    assert((nonce->auth_user == NULL) || (nonce->auth_user = auth_user));
    /* we don't lock this reference because removing the auth_user removes the 
     * hash too. Of course if that changes we're stuffed so read the code huh?
     */
    nonce->auth_user = auth_user;
}
Пример #2
0
static StoreEntry *
lru_purgeNext(RemovalPurgeWalker * walker)
{
    LruPurgeData *lru_walker = walker->_data;
    RemovalPolicy *policy = walker->_policy;
    LruPolicyData *lru = policy->_data;
    LruNode *lru_node;
    StoreEntry *entry;
  try_again:
    lru_node = lru_walker->current;
    if (!lru_node || walker->scanned >= walker->max_scan)
	return NULL;
    walker->scanned += 1;
    lru_walker->current = (LruNode *) lru_node->node.next;
    if (lru_walker->current == lru_walker->start) {
	/* Last node found */
	lru_walker->current = NULL;
    }
    entry = (StoreEntry *) lru_node->node.data;
    dlinkDelete(&lru_node->node, &lru->list);
    if (storeEntryLocked(entry)) {
	/* Shit, it is locked. we can't return this one */
	walker->locked++;
	dlinkAddTail(entry, &lru_node->node, &lru->list);
	goto try_again;
    }
    memPoolFree(lru_node_pool, lru_node);
    lru->count -= 1;
    SET_POLICY_NODE(entry, NULL);
    return entry;
}
Пример #3
0
/*
 * linebuf_new_line
 *
 * Create a new line, and link it to the given linebuf.
 * It will be initially empty.
 */
static buf_line_t *
linebuf_new_line(buf_head_t * bufhead)
{
	buf_line_t *bufline;
	dlink_node *node;

	bufline = linebuf_allocate();
	if(bufline == NULL)
		return NULL;
	++bufline_count;


	node = make_dlink_node();

	bufline->len = 0;
	bufline->terminated = 0;
	bufline->flushing = 0;
	bufline->raw = 0;

	/* Stick it at the end of the buf list */
	dlinkAddTail(bufline, node, &bufhead->list);
	bufline->refcount++;

	/* And finally, update the allocated size */
	bufhead->alloclen++;
	bufhead->numlines++;

	return bufline;
}
Пример #4
0
/*
 * Combine two user structs. ONLY to be called from within a scheme
 * module.  The scheme module is responsible for ensuring that the
 * two users _can_ be merged without invalidating all the request
 * scheme data. the scheme is also responsible for merging any user
 * related scheme data itself.
 */
void
authenticateAuthUserMerge(auth_user_t * from, auth_user_t * to)
{
	dlink_node *link, *tmplink;
	auth_user_request_t *auth_user_request;
	/*
	 * XXX combine two authuser structs. Incomplete: it should merge
	 * in hash references too and ask the module to merge in scheme
	 * data
	 */
	debug(29, 5) ("authenticateAuthUserMerge auth_user '%p' into auth_user '%p'.\n", from, to);
	link = from->requests.head;
	while (link)
	{
		auth_user_request = link->data;
		tmplink = link;
		link = link->next;
		dlinkDelete(tmplink, &from->requests);
		dlinkAddTail(auth_user_request, tmplink, &to->requests);
		auth_user_request->auth_user = to;
	}
	to->references += from->references;
	from->references = 0;
	authenticateFreeProxyAuthUser(from);
}
Пример #5
0
static struct dbuf_block *
dbuf_alloc(struct dbuf_queue *qptr)
{
  struct dbuf_block *block = BlockHeapAlloc(dbuf_heap);

  dlinkAddTail(block, make_dlink_node(), &qptr->blocks);
  return block;
}
Пример #6
0
static struct dbuf_block *
dbuf_alloc(struct dbuf_queue *qptr)
{
  struct dbuf_block *block = mp_pool_get(dbuf_pool);

  memset(block, 0, sizeof(*block));
  dlinkAddTail(block, make_dlink_node(), &qptr->blocks);
  return block;
}
Пример #7
0
static void
lru_referenced(RemovalPolicy * policy, const StoreEntry * entry,
    RemovalPolicyNode * node)
{
    LruPolicyData *lru = policy->_data;
    LruNode *lru_node = node->data;
    if (!lru_node)
	return;
    dlinkDelete(&lru_node->node, &lru->list);
    dlinkAddTail((void *) entry, &lru_node->node, &lru->list);
}
Пример #8
0
static void
lru_add(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node)
{
    LruPolicyData *lru = policy->_data;
    LruNode *lru_node;
    assert(!node->data);
    node->data = lru_node = memPoolAlloc(lru_node_pool);
    dlinkAddTail(entry, &lru_node->node, &lru->list);
    lru->count += 1;
    if (!lru->type)
	lru->type = repl_guessType(entry, node);
}
Пример #9
0
static void
authenticateAuthUserRequestSetIp(auth_user_request_t * auth_user_request, struct in_addr ipaddr, request_t * request)
{
	auth_user_ip_t *ipdata, *next;
	auth_user_t *auth_user;
	char *ip1;
	int found = 0;
	CBDATA_INIT_TYPE(auth_user_ip_t);
	if (!auth_user_request->auth_user)
		return;
	auth_user = auth_user_request->auth_user;
	next = (auth_user_ip_t *) auth_user->ip_list.head;
	/*
	 * we walk the entire list to prevent the first item in the list
	 * preventing old entries being flushed and locking a user out after
	 * a timeout+reconfigure
	 */
	while ((ipdata = next) != NULL)
	{
		next = (auth_user_ip_t *) ipdata->node.next;
		/* walk the ip list */
		if (ipdata->ipaddr.s_addr == ipaddr.s_addr)
		{
			/* This ip has already been seen. */
			found = 1;
			/* update IP ttl */
			ipdata->ip_expiretime = squid_curtime;
		}
		else if (ipdata->ip_expiretime + Config.authenticateIpTTL < squid_curtime)
		{
			/* This IP has expired - remove from the seen list */
			authenticateAuthUserRemoveIpEntry(auth_user, ipdata);
		}
	}

	authenticateAuthUserRequestLinkIp(auth_user_request, ipaddr, request);

	if (found)
		return;

	/* This ip is not in the seen list */
	ipdata = cbdataAlloc(auth_user_ip_t);
	ipdata->ip_expiretime = squid_curtime;
	ipdata->ipaddr = ipaddr;
	dlinkAddTail(ipdata, &ipdata->node, &auth_user->ip_list);
	auth_user->ipcount++;

	ip1 = xstrdup(inet_ntoa(ipaddr));
	debug(29, 2) ("authenticateAuthUserRequestSetIp: user '%s' has been seen at a new IP address (%s)\n", authenticateUserUsername(auth_user), ip1);
	safe_free(ip1);
}
Пример #10
0
static void
StatefulEnqueue(statefulhelper * hlp, helper_stateful_request * r)
{
    dlink_node *link = memAllocate(MEM_DLINK_NODE);
    dlinkAddTail(r, link, &hlp->queue);
    hlp->stats.queue_size++;
    if (hlp->stats.queue_size < hlp->n_running)
	return;
    if (hlp->stats.queue_size > hlp->stats.max_queue_size)
	hlp->stats.max_queue_size = hlp->stats.queue_size;
    if (hlp->stats.queue_size > hlp->n_running * 5)
	fatalf("Too many queued %s requests (%d on %d)", hlp->id_name, hlp->stats.queue_size, hlp->n_running);
    if (squid_curtime - hlp->last_queue_warn < 30)
	return;
    if (shutting_down || reconfiguring)
	return;
    hlp->last_queue_warn = squid_curtime;
    debug(84, 1) ("WARNING: All %s processes are busy.\n", hlp->id_name);
    debug(84, 1) ("WARNING: up to %d pending requests queued\n", hlp->stats.max_queue_size);
    if (hlp->stats.max_queue_size > 1)
	debug(84, 1) ("Consider increasing the number of %s processes to at least %d in your config file.\n", hlp->id_name, hlp->n_running + hlp->stats.max_queue_size);
    hlp->stats.max_queue_size = hlp->stats.queue_size;
}
Пример #11
0
int
main(int argc, char *argv[])
{
	/* Check to see if the user is running us as root, which is a nono */
	if(geteuid() == 0)
	{
		fprintf(stderr, "Don't run ircd as root!!!\n");
		return -1;
	}

	/*
	 * save server boot time right away, so getrusage works correctly
	 */
	set_time();
	/*
	 * Setup corefile size immediately after boot -kre
	 */
	setup_corefile();

	/*
	 * set initialVMTop before we allocate any memory
	 */
	initialVMTop = get_vm_top();

	ServerRunning = 0;
	/* It ain't random, but it ought to be a little harder to guess */
	srand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20)));
	memset(&me, 0, sizeof(me));
	memset(&meLocalUser, 0, sizeof(meLocalUser));
	me.localClient = &meLocalUser;

	/* Make sure all lists are zeroed */
	memset(&unknown_list, 0, sizeof(unknown_list));
	memset(&lclient_list, 0, sizeof(lclient_list));
	memset(&serv_list, 0, sizeof(serv_list));
	memset(&global_serv_list, 0, sizeof(global_serv_list));
	memset(&oper_list, 0, sizeof(oper_list));

	dlinkAddTail(&me, &me.node, &global_client_list);

	memset((void *) &Count, 0, sizeof(Count));
	memset((void *) &ServerInfo, 0, sizeof(ServerInfo));
	memset((void *) &AdminInfo, 0, sizeof(AdminInfo));

	/* Initialise the channel capability usage counts... */
	init_chcap_usage_counts();

	ConfigFileEntry.dpath = DPATH;
	ConfigFileEntry.configfile = CPATH;	/* Server configuration file */
	ConfigFileEntry.klinefile = KPATH;	/* Server kline file */
	ConfigFileEntry.dlinefile = DLPATH;	/* dline file */
	ConfigFileEntry.xlinefile = XPATH;
	ConfigFileEntry.resvfile = RESVPATH;
	ConfigFileEntry.connect_timeout = 30;	/* Default to 30 */
	myargv = argv;
	umask(077);		/* better safe than sorry --SRB */

	parseargs(&argc, &argv, myopts);

	if(printVersion)
	{
		printf("ircd: version %s\n", ircd_version);
		exit(EXIT_SUCCESS);
	}

	if(chdir(ConfigFileEntry.dpath))
	{
		fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno));
		exit(EXIT_FAILURE);
	}

	setup_signals();

#ifdef __CYGWIN__
	server_state_foreground = 1;
#endif

	if (testing_conf)
		server_state_foreground = 1;

	/* We need this to initialise the fd array before anything else */
	fdlist_init();
	if(!server_state_foreground)
	{
		comm_close_all();
	}


	/* Check if there is pidfile and daemon already running */
	if(!testing_conf)
	{
		check_pidfile(pidFileName);

		if(!server_state_foreground)
			make_daemon();
		else
			print_startup(getpid());
	}

	init_netio();		/* This needs to be setup early ! -- adrian */

	/* Init the event subsystem */
	eventInit();
	init_sys();

	init_main_logfile();
	initBlockHeap();
	init_dlink_nodes();
	init_patricia();
	newconf_init();
	init_s_conf();
	init_s_newconf();
	linebuf_init();		/* set up some linebuf stuff to control paging */
	init_hash();
	clear_scache_hash_table();	/* server cache name table */
	init_host_hash();
	clear_hash_parse();
	init_client();
	initUser();
	init_channels();
	initclass();
	initwhowas();
	init_stats();
	init_hook();
	init_reject();
	init_cache();
	init_monitor();
	load_all_modules(1);
#ifndef STATIC_MODULES
	load_core_modules(1);
#endif
	init_auth();		/* Initialise the auth code */
	init_resolver();	/* Needs to be setup before the io loop */

	if (testing_conf)
		fprintf(stderr, "\nBeginning config test\n");
	read_conf_files(YES);	/* cold start init conf files */
	rehash_bans(0);
#ifndef STATIC_MODULES

	mod_add_path(MODULE_DIR); 
	mod_add_path(MODULE_DIR "/autoload"); 
#endif

	initialize_server_capabs();	/* Set up default_server_capabs */
	initialize_global_set_options();

	if(ServerInfo.name == NULL)
	{
		fprintf(stderr, "ERROR: No server name specified in serverinfo block.\n");
		ilog(L_MAIN, "No server name specified in serverinfo block.");
		exit(EXIT_FAILURE);
	}
	strlcpy(me.name, ServerInfo.name, sizeof(me.name));

	if(ServerInfo.sid[0] == '\0')
	{
		fprintf(stderr, "ERROR: No server sid specified in serverinfo block.\n");
		ilog(L_MAIN, "No server sid specified in serverinfo block.");
		exit(EXIT_FAILURE);
	}
	strcpy(me.id, ServerInfo.sid);
	init_uid();

	/* serverinfo{} description must exist.  If not, error out. */
	if(ServerInfo.description == NULL)
	{
		fprintf(stderr, "ERROR: No server description specified in serverinfo block.\n");
		ilog(L_MAIN, "ERROR: No server description specified in serverinfo block.");
		exit(EXIT_FAILURE);
	}
	strlcpy(me.info, ServerInfo.description, sizeof(me.info));

	if (testing_conf)
	{
		fprintf(stderr, "\nConfig testing complete.\n");
		fflush(stderr);
		exit(EXIT_SUCCESS);
	}

	me.from = &me;
	me.servptr = &me;
	SetMe(&me);
	make_server(&me);
	me.serv->up = me.name;
	startup_time = CurrentTime;
	add_to_client_hash(me.name, &me);
	add_to_id_hash(me.id, &me);

	dlinkAddAlloc(&me, &global_serv_list);

	check_class();
	write_pidfile(pidFileName);
	load_help();
	open_logfiles();

	ilog(L_MAIN, "Server Ready");

	eventAddIsh("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_TIME);

	/* We want try_connections to be called as soon as possible now! -- adrian */
	/* No, 'cause after a restart it would cause all sorts of nick collides */
	/* um.  by waiting even longer, that just means we have even *more*
	 * nick collisions.  what a stupid idea. set an event for the IO loop --fl
	 */
	eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
	eventAddOnce("try_connections_startup", try_connections, NULL, 0);

	eventAddIsh("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);

	/* Setup the timeout check. I'll shift it later :)  -- adrian */
	eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1);

	if(ConfigServerHide.links_delay > 0)
		eventAddIsh("cache_links", cache_links, NULL,
			    ConfigServerHide.links_delay);
	else
		ConfigServerHide.links_disabled = 1;

	if(splitmode)
		eventAdd("check_splitmode", check_splitmode, NULL, 2);

	ServerRunning = 1;

	io_loop();
	return 0;
}
Пример #12
0
void
helperOpenServers(helper * hlp)
{
    char *s;
    char *progname;
    char *shortname;
    char *procname;
    const char *args[HELPER_MAX_ARGS];
    char fd_note_buf[FD_DESC_SZ];
    helper_server *srv;
    int nargs = 0;
    int k;
    int x;
    int rfd;
    int wfd;
    wordlist *w;
    if (hlp->cmdline == NULL)
	return;
    progname = hlp->cmdline->key;
    if ((s = strrchr(progname, '/')))
	shortname = xstrdup(s + 1);
    else
	shortname = xstrdup(progname);
    debug(84, 1) ("helperOpenServers: Starting %d '%s' processes\n",
	hlp->n_to_start, shortname);
    procname = xmalloc(strlen(shortname) + 3);
    snprintf(procname, strlen(shortname) + 3, "(%s)", shortname);
    args[nargs++] = procname;
    for (w = hlp->cmdline->next; w && nargs < HELPER_MAX_ARGS; w = w->next)
	args[nargs++] = w->key;
    args[nargs++] = NULL;
    assert(nargs <= HELPER_MAX_ARGS);
    for (k = 0; k < hlp->n_to_start; k++) {
	getCurrentTime();
	rfd = wfd = -1;
	x = ipcCreate(hlp->ipc_type,
	    progname,
	    args,
	    shortname,
	    &rfd,
	    &wfd);
	if (x < 0) {
	    debug(84, 1) ("WARNING: Cannot run '%s' process.\n", progname);
	    continue;
	}
	hlp->n_running++;
	srv = cbdataAlloc(helper_server);
	srv->pid = x;
	srv->flags.alive = 1;
	srv->index = k;
	srv->rfd = rfd;
	srv->wfd = wfd;
	srv->buf = memAllocate(MEM_8K_BUF);
	srv->buf_sz = 8192;
	srv->offset = 0;
	srv->parent = hlp;
	cbdataLock(hlp);	/* lock because of the parent backlink */
	dlinkAddTail(srv, &srv->link, &hlp->servers);
	if (rfd == wfd) {
	    snprintf(fd_note_buf, FD_DESC_SZ, "%s #%d", shortname, k + 1);
	    fd_note(rfd, fd_note_buf);
	} else {
	    snprintf(fd_note_buf, FD_DESC_SZ, "reading %s #%d", shortname, k + 1);
	    fd_note(rfd, fd_note_buf);
	    snprintf(fd_note_buf, FD_DESC_SZ, "writing %s #%d", shortname, k + 1);
	    fd_note(wfd, fd_note_buf);
	}
	commSetNonBlocking(rfd);
	if (wfd != rfd)
	    commSetNonBlocking(wfd);
	comm_add_close_handler(rfd, helperServerFree, srv);
    }
    hlp->last_restart = squid_curtime;
    safe_free(shortname);
    safe_free(procname);
    helperKickQueue(hlp);
}