diff options
Diffstat (limited to 'source4/smbd/conn.c')
-rw-r--r-- | source4/smbd/conn.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/source4/smbd/conn.c b/source4/smbd/conn.c new file mode 100644 index 0000000000..0498b3cb5d --- /dev/null +++ b/source4/smbd/conn.c @@ -0,0 +1,158 @@ +/* + Unix SMB/CIFS implementation. + Manage connections_struct structures + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Alexander Bokovoy 2002 + + This program 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 of the License, or + (at your option) any later version. + + This program 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* set these to define the limits of the server. NOTE These are on a + per-client basis. Thus any one machine can't connect to more than + MAX_CONNECTIONS services, but any number of machines may connect at + one time. */ +#define MAX_CONNECTIONS 128 + +/**************************************************************************** +init the conn structures +****************************************************************************/ +void conn_init(struct server_context *smb) +{ + smb->tree.bmap = bitmap_allocate(MAX_CONNECTIONS); +} + +/**************************************************************************** +check if a snum is in use +****************************************************************************/ +BOOL conn_snum_used(struct server_context *smb, int snum) +{ + struct tcon_context *conn; + for (conn=smb->tree.connections;conn;conn=conn->next) { + if (conn->service == snum) { + return(True); + } + } + return(False); +} + + +/**************************************************************************** +find a conn given a cnum +****************************************************************************/ +struct tcon_context *conn_find(struct server_context *smb, unsigned cnum) +{ + int count=0; + struct tcon_context *conn; + + for (conn=smb->tree.connections;conn;conn=conn->next,count++) { + if (conn->cnum == cnum) { + if (count > 10) { + DLIST_PROMOTE(smb->tree.connections, conn); + } + return conn; + } + } + + return NULL; +} + + +/**************************************************************************** + find first available connection slot, starting from a random position. +The randomisation stops problems with the server dieing and clients +thinking the server is still available. +****************************************************************************/ +struct tcon_context *conn_new(struct server_context *smb) +{ + TALLOC_CTX *mem_ctx; + struct tcon_context *conn; + int i; + + i = bitmap_find(smb->tree.bmap, 1); + + if (i == -1) { + DEBUG(1,("ERROR! Out of connection structures\n")); + return NULL; + } + + mem_ctx = talloc_init("tcon_context[%d]", i); + + conn = (struct tcon_context *)talloc(mem_ctx, sizeof(*conn)); + if (!conn) return NULL; + + ZERO_STRUCTP(conn); + + conn->mem_ctx = mem_ctx; + conn->cnum = i; + conn->smb = smb; + + bitmap_set(smb->tree.bmap, i); + + smb->tree.num_open++; + + DLIST_ADD(smb->tree.connections, conn); + + return conn; +} + +/**************************************************************************** +close all conn structures +****************************************************************************/ +void conn_close_all(struct server_context *smb) +{ + struct tcon_context *conn, *next; + for (conn=smb->tree.connections;conn;conn=next) { + next=conn->next; + close_cnum(conn); + } +} + + +#if REWRITE_REMOVED +/**************************************************************************** +clear a vuid out of the validity cache, and as the 'owner' of a connection. +****************************************************************************/ +void conn_clear_vuid_cache(struct server_context *smb, uint16 vuid) +{ + struct tcon_context *conn; + unsigned int i; + + for (conn=smb->tree.connections;conn;conn=conn->next) { + for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) { + if (conn->vuid_cache.list[i] == vuid) { + conn->vuid_cache.list[i] = UID_FIELD_INVALID; + } + } + } +} +#endif + +/**************************************************************************** + Free a conn structure. +****************************************************************************/ + +void conn_free(struct server_context *smb, struct tcon_context *conn) +{ + DLIST_REMOVE(smb->tree.connections, conn); + + bitmap_clear(smb->tree.bmap, conn->cnum); + smb->tree.num_open--; + + ZERO_STRUCTP(conn); + SAFE_FREE(conn); +} + |