]> git.sur5r.net Git - openldap/blob - servers/slapd/connection.c
Everything compiles.... but tests fail...
[openldap] / servers / slapd / connection.c
1 #define DISABLE_BRIDGE
2 #include "portable.h"
3
4 #include <stdio.h>
5 #include <ac/string.h>
6 #include <ac/time.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <errno.h>
10 #include <signal.h>
11 #include "slap.h"
12
13 extern Operation        *op_add();
14 extern int              active_threads;
15 extern pthread_mutex_t  active_threads_mutex;
16 extern pthread_mutex_t  new_conn_mutex;
17 extern long             ops_initiated;
18 extern long             ops_completed;
19 extern pthread_mutex_t  ops_mutex;
20 extern pthread_t        listener_tid;
21
22 #ifdef DECL_SYS_ERRLIST
23 extern int              sys_nerr;
24 extern char             *sys_errlist[];
25 #endif
26
27 struct co_arg {
28         Connection      *co_conn;
29         Operation       *co_op;
30 };
31
32 /*
33  * connection_activity - handle the request operation op on connection
34  * conn.  This routine figures out what kind of operation it is and
35  * calls the appropriate stub to handle it.
36  */
37
38 static void
39 connection_operation( struct co_arg *arg )
40 {
41         unsigned long   len;
42
43         pthread_mutex_lock( &arg->co_conn->c_opsmutex );
44         arg->co_conn->c_opsinitiated++;
45         pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
46
47         pthread_mutex_lock( &ops_mutex );
48         ops_initiated++;
49         pthread_mutex_unlock( &ops_mutex );
50
51         switch ( arg->co_op->o_tag ) {
52         case LDAP_REQ_BIND:
53                 do_bind( arg->co_conn, arg->co_op );
54                 break;
55
56 #ifdef COMPAT30
57         case LDAP_REQ_UNBIND_30:
58 #endif
59         case LDAP_REQ_UNBIND:
60                 do_unbind( arg->co_conn, arg->co_op );
61                 break;
62
63         case LDAP_REQ_ADD:
64                 do_add( arg->co_conn, arg->co_op );
65                 break;
66
67 #ifdef COMPAT30
68         case LDAP_REQ_DELETE_30:
69 #endif
70         case LDAP_REQ_DELETE:
71                 do_delete( arg->co_conn, arg->co_op );
72                 break;
73
74         case LDAP_REQ_MODRDN:
75                 do_modrdn( arg->co_conn, arg->co_op );
76                 break;
77
78         case LDAP_REQ_MODIFY:
79                 do_modify( arg->co_conn, arg->co_op );
80                 break;
81
82         case LDAP_REQ_COMPARE:
83                 do_compare( arg->co_conn, arg->co_op );
84                 break;
85
86         case LDAP_REQ_SEARCH:
87                 do_search( arg->co_conn, arg->co_op );
88                 break;
89
90 #ifdef COMPAT30
91         case LDAP_REQ_ABANDON_30:
92 #endif
93         case LDAP_REQ_ABANDON:
94                 do_abandon( arg->co_conn, arg->co_op );
95                 break;
96
97         default:
98                 Debug( LDAP_DEBUG_ANY, "unknown request 0x%x\n",
99                     arg->co_op->o_tag, 0, 0 );
100                 break;
101         }
102
103         pthread_mutex_lock( &arg->co_conn->c_opsmutex );
104         arg->co_conn->c_opscompleted++;
105         op_delete( &arg->co_conn->c_ops, arg->co_op );
106         pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
107
108         free( (char *) arg );
109
110         pthread_mutex_lock( &ops_mutex );
111         ops_completed++;
112         pthread_mutex_unlock( &ops_mutex );
113
114         pthread_mutex_lock( &active_threads_mutex );
115         active_threads--;
116         pthread_mutex_unlock( &active_threads_mutex );
117 }
118
119 void
120 connection_activity(
121     Connection *conn
122 )
123 {
124         pthread_attr_t  attr;
125         struct co_arg   *arg;
126         unsigned long   tag, len;
127         long            msgid;
128         BerElement      *ber;
129         char            *tmpdn;
130
131         if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
132             == NULL ) {
133                 Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
134                 return;
135         }
136
137         errno = 0;
138         if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
139             != LDAP_TAG_MESSAGE ) {
140                 Debug( LDAP_DEBUG_TRACE,
141                     "ber_get_next on fd %d failed errno %d (%s)\n",
142                     conn->c_sb.sb_sd, errno, errno > -1 && errno < sys_nerr ?
143                     sys_errlist[errno] : "unknown" );
144                 Debug( LDAP_DEBUG_TRACE, "*** got %d of %d so far\n",
145                     conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf,
146                     conn->c_currentber->ber_len, 0 );
147
148                 if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
149                         /* log, close and send error */
150                         ber_free( conn->c_currentber, 1 );
151                         conn->c_currentber = NULL;
152
153                         close_connection( conn, conn->c_connid, -1 );
154                 }
155
156                 return;
157         }
158         ber = conn->c_currentber;
159         conn->c_currentber = NULL;
160
161         if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
162                 /* log, close and send error */
163                 Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%x\n", tag, 0,
164                     0 );
165                 ber_free( ber, 1 );
166
167                 close_connection( conn, conn->c_connid, -1 );
168                 return;
169         }
170
171         if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
172                 /* log, close and send error */
173                 Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%x\n", tag, 0,
174                     0 );
175                 ber_free( ber, 1 );
176
177                 close_connection( conn, conn->c_connid, -1 );
178                 return;
179         }
180
181 #ifdef COMPAT30
182         if ( conn->c_version == 30 ) {
183                 (void) ber_skip_tag( ber, &len );
184         }
185 #endif
186
187         arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
188         arg->co_conn = conn;
189
190         pthread_mutex_lock( &conn->c_dnmutex );
191         if ( conn->c_dn != NULL ) {
192                 tmpdn = strdup( conn->c_dn );
193         } else {
194                 tmpdn = NULL;
195         }
196         pthread_mutex_unlock( &conn->c_dnmutex );
197
198         pthread_mutex_lock( &conn->c_opsmutex );
199         arg->co_op = op_add( &conn->c_ops, ber, msgid, tag, tmpdn,
200             conn->c_opsinitiated, conn->c_connid );
201         pthread_mutex_unlock( &conn->c_opsmutex );
202
203         if ( tmpdn != NULL ) {
204                 free( tmpdn );
205         }
206
207         pthread_attr_init( &attr );
208         pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
209 #ifndef THREAD_MIT_PTHREADS
210         /* POSIX_THREADS or compatible
211          * This is a draft 10 or standard pthreads implementation
212          */
213         if ( pthread_create( &arg->co_op->o_tid, &attr,
214             (void *) connection_operation, (void *) arg ) != 0 ) {
215                 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
216         } else {
217                 pthread_mutex_lock( &active_threads_mutex );
218                 active_threads++;
219                 pthread_mutex_unlock( &active_threads_mutex );
220         }
221 #else   /* !THREAD_MIT_PTHREAD */
222         /*
223          * This is a draft 4 or earlier pthreads implementation
224          */
225         if ( pthread_create( &arg->co_op->o_tid, attr,
226             (void *) connection_operation, (void *) arg ) != 0 ) {
227                 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
228         } else {
229                 pthread_mutex_lock( &active_threads_mutex );
230                 active_threads++;
231                 pthread_mutex_unlock( &active_threads_mutex );
232         }
233 #endif  /* !THREAD_MIT_PTHREAD */
234         pthread_attr_destroy( &attr );
235 }