per_dnet.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <sys/sysmacros.h>
#include <assert.h>
#include <errno.h>
#include <syslog.h>
#include <fcntl.h>
#include <netinet/in_systm.h>
#include "dhcpd.h"
#include "interfaces.h"
#include <locale.h>
/*
* This file contains the access routines for the dhcp databases.
*/
/*
* Initialize global per network hash table.
*
* Per-bucket rwlocks reduce lock contention between interface and
* client threads.
*
* Performance: dynamically calculate hash table size.
*/
int
initntab(void)
{
char **listppp;
DSVC_SUCCESS) {
if (listppp) {
ind++)
}
}
B_TRUE);
}
/*
* open_dnet: Open the appropriate dhcp database given a network address and
* a subnet mask. These in_addr's are expected in network order.
*
* Returns: DSVC_SUCCESS for success or dsvc error.
*/
int
{
int err;
int hsize = 0;
/* Locate existing dnet. */
return (DSVC_INTERNAL);
return (DSVC_BUSY);
} else {
return (DSVC_SUCCESS);
}
}
/* Allocate new dnet. */
/* Allocate hash tables. */
if (max_clients != -1)
hsize = max_clients;
return (DSVC_INTERNAL);
}
return (DSVC_INTERNAL);
}
if (err != DSVC_SUCCESS) {
return (err);
}
/* Find out how many addresses the server owns in this datastore */
if (err != DSVC_SUCCESS) {
return (err);
}
}
/* Another thread has begun work on this net. */
#ifdef DEBUG
#endif /* DEBUG */
return (DSVC_BUSY);
}
return (DSVC_SUCCESS);
}
/*
* close_dnet: Closes specified dhcp-network database.
*
* delete - immediately delete.
*/
void
{
}
/*
* get_dnet: Given a network name, look it up in the hash table.
* Returns ptr to dsvc_dnet_t structure, NULL if error occurs.
*/
static dsvc_dnet_t *
{
/* refresh pnd hash entry timer */
return (pnd);
}
/*
* unhash_dnet: Free a datastore reference.
*
* Aging in hash routines will trigger freeing of unused references.
*/
/*ARGSUSED*/
static boolean_t
{
int err = 0;
int nthreads;
int refcnt;
return (B_FALSE);
/* Mark as closing. */
/*
* Wait for any remaining thread(s) to exit.
*/
/*
* Wait for 1ms to avoid stalling monitor threads.
* cond_wait() not used to avoid thread synchronization
* overhead.
*/
/* Threads will exit. */
}
}
/* Free threads. */
}
/* Free deferred thread work. */
}
/* Free clients. */
}
/* Free cached datastore records. */
}
}
"Error %d while closing for network %s\n",
}
}
return (B_TRUE);
}
/*
* dnet_cmp: Compare datastore references by network address.
*/
static int
{
}
/*
* open_clnt: Open the appropriate dhcp client given a network
* database and client id.
*
* Returns: DSVC_SUCCESS for success or errno if an error occurs.
*
* pnd - per net struct
* pcdp - client struct returned here
* cid - clientid
* cid_len - cid length
* nocreate - if set, client struct must previously exist
*/
int
{
/* Network is closing. */
return (DSVC_BUSY);
/* Locate existing client. */
/* Client is closing - temporarily busy. */
return (DSVC_BUSY);
}
return (DSVC_SUCCESS);
}
return (DSVC_NOENT);
/* Allocate new client. */
if (max_clients != -1) {
/*
* Performance/DOS: dsvc_clnt_t structs are normally
* freed when the protocol conversation completes,
* or when garbage collected (see hash.c). In
* certain error scenarios (e.g. DOS attacks, or
* network failures where large numbers of clients
* begin protocol conversations that never complete)
* the server will become unresponsive. To detect
* these scenarios, free slot time is observed, and
* after a grace period (2 * the offer time the currently
* allocated clients are allowed), clients are randomly
* deleted.
*/
/* Keep track of last time there were free slots. */
/* Wait for other clients to complete. */
return (DSVC_INTERNAL);
} else {
/* Forcibly delete a client to free a slot. */
}
} else
/* Another thread has begun work on this client */
#ifdef DEBUG
#endif /* DEBUG */
return (DSVC_BUSY);
}
return (DSVC_SUCCESS);
}
/*
* close_clnt: Closes specified client.
*
* delete - immediately delete.
*/
void
{
}
/*
* get_client: Given a client name, look it up in the per client hash table.
* Returns ptr to dsvc_clnt_t structure, NULL if error occurs.
*/
static dsvc_clnt_t *
{
/* refresh client hash entry's timer */
return (pcd);
}
/*
* unhash_clnt: Free a client structure.
*
* Aging in hash routines will trigger freeing of unused references.
*/
/*ARGSUSED*/
static boolean_t
{
int refcnt;
/*
* Wait for thread(s) accessing pcd to drop references.
*/
/*
* Wait for 1ms to avoid stalling monitor threads.
* cond_wait() not used to avoid thread synchronization
* overhead.
*/
}
return (B_TRUE);
}
/*
* unhash_offer: Free offer associated with a client structure.
*
* Aging in hash routines will trigger freeing of expired offers.
*/
static boolean_t
{
char ntoab[INET_ADDRSTRLEN];
if (debug)
/*
* Worker thread is currently active. To avoid
* unnecessary thread synchronization, defer
* freeing the offer until the worker thread has
* completed.
*/
} else
} else
return (ret);
}
/*
* clnt_cmp: Compare client structures by cid.
*/
static int
{
}
/*
* clnt_netcmp Compare clients by network address. This is used to maintain
* the itable hash table of client addresses.
*/
int
{
}
/*
* close_clnts: Free the ntable hash table and associated client structs.
* Table walk frees each per network and client struct.
*/
void
close_clnts(void)
{
}