]> git.sur5r.net Git - openldap/blob - servers/ldapd/message.c
Resync with HEAD
[openldap] / servers / ldapd / message.c
1 /*
2  * Copyright (c) 1990 Regents of the University of Michigan.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of Michigan at Ann Arbor. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <quipu/commonarg.h>
19 #include <quipu/ds_error.h>
20 #include "lber.h"
21 #include "ldap.h"
22 #include "common.h"
23
24 static struct msg       *messages;
25
26 struct msg *add_msg(
27     int                 msgid,
28     int                 msgtype,
29     BerElement          *ber,
30     struct conn         *dsaconn,
31     int                 udp,
32     struct sockaddr     *clientaddr
33 )
34 {
35         struct msg              *new;
36         static int              uniqid = 0;
37
38         /* make a new message */
39         if ( (new = (struct msg *) malloc( sizeof(struct msg) )) == NULL ) {
40                 Debug( LDAP_DEBUG_ANY, "addmsg: malloc failed\n", 0, 0, 0 );
41                 return( NULL );
42         }
43         new->m_msgid = msgid;
44         new->m_uniqid = ++uniqid;
45         new->m_msgtype = msgtype;
46         new->m_ber = ber;
47         new->m_mods = NULL;
48         new->m_conn = dsaconn;
49         new->m_conn->c_refcnt++;
50         new->m_next = NULL;
51
52 #ifdef CLDAP
53         new->m_cldap = udp;
54         new->m_searchbase = NULLDN;
55
56         if ( udp ) {
57                 new->m_clientaddr = *clientaddr;
58                 Debug( LDAP_DEBUG_TRACE, "udp message from %s port %d\n", 
59                     inet_ntoa( ((struct sockaddr_in *)clientaddr)->sin_addr ),
60                     ((struct sockaddr_in *)clientaddr)->sin_port, 0 );
61         }
62 #endif
63
64         /* add it to the front of the queue */
65         new->m_next = messages;
66         messages = new;
67
68         return( new );
69 }
70
71 struct msg *get_msg( int uniqid )
72 {
73         struct msg      *tmp;
74
75         for ( tmp = messages; tmp != NULL; tmp = tmp->m_next ) {
76                 if ( tmp->m_uniqid == uniqid )
77                         return( tmp );
78         }
79
80         return( NULL );
81 }
82
83 int
84 del_msg( struct msg *m )
85 {
86         struct msg      *cur, *prev;
87
88         prev = NULL;
89         for ( cur = messages; cur != NULL; cur = cur->m_next ) {
90                 if ( cur == m )
91                         break;
92                 prev = cur;
93         }
94
95         if ( cur == NULL ) {
96                 Debug( LDAP_DEBUG_ANY, "delmsg: cannot find msg %x\n", m,
97                     0, 0 );
98                 return( -1 );
99         }
100
101         if ( prev == NULL ) {
102                 messages = cur->m_next;
103         } else {
104                 prev->m_next = cur->m_next;
105         }
106         conn_free( cur->m_conn );
107         modlist_free( cur->m_mods );
108         ber_free( cur->m_ber, 1 );
109 #ifdef CLDAP
110         if ( cur->m_searchbase != NULLDN ) {
111             dn_free( cur->m_searchbase );
112         }
113 #endif /* CLDAP */
114         free( (char *) cur );
115
116         return( 0 );
117 }
118
119 /*
120  * send_msg - Send a messge in response to every outstanding request on
121  * a given connection.  This is used, for example, when an association to
122  * a dsa fails.  It deletes messages to which it responds.
123  */
124
125 void
126 send_msg(
127     struct conn *conn,
128     Sockbuf     *clientsb,
129     int         err,
130     char        *str
131 )
132 {
133         struct msg      *tmp, *next;
134
135         next = NULL;
136         for ( tmp = messages; tmp != NULL; tmp = next ) {
137                 next = tmp->m_next;
138
139                 if ( tmp->m_conn == conn ) {
140                         send_ldap_msgresult( clientsb, tmp->m_msgtype, tmp,
141                             err, NULL, str );
142                 }
143
144                 del_msg( tmp );
145         }
146 }
147
148
149 #ifdef CLDAP
150 struct msg *
151 get_cldap_msg(
152     int                 msgid,
153     int                 msgtype,
154     struct sockaddr     *fromaddr
155 )
156 {
157         struct msg      *tmp;
158
159         for ( tmp = messages; tmp != NULL; tmp = tmp->m_next ) {
160                 if ( tmp->m_cldap && tmp->m_msgid == msgid &&
161                     tmp->m_msgtype == msgtype &&
162                     ((struct sockaddr_in *)&tmp->m_clientaddr)->sin_port ==
163                     ((struct sockaddr_in *)fromaddr)->sin_port &&
164                     ((struct sockaddr_in *)&tmp->m_clientaddr)->sin_addr.s_addr
165                     == ((struct sockaddr_in *)fromaddr)->sin_addr.s_addr ) {
166                         break;
167                 }
168         }
169
170         return( tmp );
171 }
172 #endif /* CLDAP */