490dde979c1b1897ff30d7f70b9807a8f0d23e1c
[jelmer/samba4-debian.git] / source / smb_server / conn.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Manage connections_struct structures
4    Copyright (C) Andrew Tridgell 1998
5    Copyright (C) Alexander Bokovoy 2002
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /* set these to define the limits of the server. NOTE These are on a
25    per-client basis. Thus any one machine can't connect to more than
26    MAX_CONNECTIONS services, but any number of machines may connect at
27    one time. */
28 #define MAX_CONNECTIONS 128
29
30 /****************************************************************************
31 init the conn structures
32 ****************************************************************************/
33 void conn_init(struct server_context *smb)
34 {
35         smb->tree.bmap = bitmap_allocate(MAX_CONNECTIONS);
36 }
37
38 /****************************************************************************
39 check if a snum is in use
40 ****************************************************************************/
41 BOOL conn_snum_used(struct server_context *smb, int snum)
42 {
43         struct tcon_context *conn;
44         for (conn=smb->tree.connections;conn;conn=conn->next) {
45                 if (conn->service == snum) {
46                         return(True);
47                 }
48         }
49         return(False);
50 }
51
52
53 /****************************************************************************
54 find a conn given a cnum
55 ****************************************************************************/
56 struct tcon_context *conn_find(struct server_context *smb, uint_t cnum)
57 {
58         int count=0;
59         struct tcon_context *conn;
60
61         for (conn=smb->tree.connections;conn;conn=conn->next,count++) {
62                 if (conn->cnum == cnum) {
63                         if (count > 10) {
64                                 DLIST_PROMOTE(smb->tree.connections, conn);
65                         }
66                         return conn;
67                 }
68         }
69
70         return NULL;
71 }
72
73
74 /****************************************************************************
75   find first available connection slot, starting from a random position.
76 The randomisation stops problems with the server dieing and clients
77 thinking the server is still available.
78 ****************************************************************************/
79 struct tcon_context *conn_new(struct server_context *smb)
80 {
81         TALLOC_CTX *mem_ctx;
82         struct tcon_context *conn;
83         int i;
84
85         i = bitmap_find(smb->tree.bmap, 1);
86         
87         if (i == -1) {
88                 DEBUG(1,("ERROR! Out of connection structures\n"));            
89                 return NULL;
90         }
91
92         mem_ctx = talloc_init("tcon_context[%d]", i);
93
94         conn = (struct tcon_context *)talloc(mem_ctx, sizeof(*conn));
95         if (!conn) return NULL;
96
97         ZERO_STRUCTP(conn);
98
99         conn->mem_ctx = mem_ctx;
100         conn->cnum = i;
101         conn->smb = smb;
102
103         bitmap_set(smb->tree.bmap, i);
104
105         smb->tree.num_open++;
106
107         DLIST_ADD(smb->tree.connections, conn);
108
109         return conn;
110 }
111
112 /****************************************************************************
113 close all conn structures
114 ****************************************************************************/
115 void conn_close_all(struct server_context *smb)
116 {
117         struct tcon_context *conn, *next;
118         for (conn=smb->tree.connections;conn;conn=next) {
119                 next=conn->next;
120                 close_cnum(conn);
121         }
122 }
123
124
125 #if REWRITE_REMOVED
126 /****************************************************************************
127 clear a vuid out of the validity cache, and as the 'owner' of a connection.
128 ****************************************************************************/
129 void conn_clear_vuid_cache(struct server_context *smb, uint16_t vuid)
130 {
131         struct tcon_context *conn;
132         uint_t i;
133
134         for (conn=smb->tree.connections;conn;conn=conn->next) {
135                 for (i=0;i<conn->vuid_cache.entries && i< VUID_CACHE_SIZE;i++) {
136                         if (conn->vuid_cache.list[i] == vuid) {
137                                 conn->vuid_cache.list[i] = UID_FIELD_INVALID;
138                         }
139                 }
140         }
141 }
142 #endif
143
144 /****************************************************************************
145  Free a conn structure.
146 ****************************************************************************/
147
148 void conn_free(struct server_context *smb, struct tcon_context *conn)
149 {
150         DLIST_REMOVE(smb->tree.connections, conn);
151
152         bitmap_clear(smb->tree.bmap, conn->cnum);
153         smb->tree.num_open--;
154
155         talloc_destroy(conn->mem_ctx);
156 }
157