openldap/servers/ldapd/message.c
1998-11-05 05:47:02 +00:00

176 lines
3.7 KiB
C

/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <quipu/commonarg.h>
#include <quipu/ds_error.h>
#include "lber.h"
#include "ldap.h"
#include "common.h"
static struct msg *messages;
struct msg *add_msg(
int msgid,
int msgtype,
BerElement *ber,
struct conn *dsaconn,
int udp,
struct sockaddr *clientaddr
)
{
struct msg *new;
static int uniqid = 0;
/* make a new message */
if ( (new = (struct msg *) malloc( sizeof(struct msg) )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "addmsg: malloc failed\n", 0, 0, 0 );
return( NULL );
}
new->m_msgid = msgid;
new->m_uniqid = ++uniqid;
new->m_msgtype = msgtype;
new->m_ber = ber;
new->m_mods = NULL;
new->m_conn = dsaconn;
new->m_conn->c_refcnt++;
new->m_next = NULL;
#ifdef LDAP_CONNECTIONLESS
new->m_cldap = udp;
new->m_searchbase = NULLDN;
if ( udp ) {
new->m_clientaddr = *clientaddr;
Debug( LDAP_DEBUG_TRACE, "udp message from %s port %d\n",
inet_ntoa( ((struct sockaddr_in *)clientaddr)->sin_addr ),
((struct sockaddr_in *)clientaddr)->sin_port, 0 );
}
#endif
/* add it to the front of the queue */
new->m_next = messages;
messages = new;
return( new );
}
struct msg *get_msg( int uniqid )
{
struct msg *tmp;
for ( tmp = messages; tmp != NULL; tmp = tmp->m_next ) {
if ( tmp->m_uniqid == uniqid )
return( tmp );
}
return( NULL );
}
int
del_msg( struct msg *m )
{
struct msg *cur, *prev;
prev = NULL;
for ( cur = messages; cur != NULL; cur = cur->m_next ) {
if ( cur == m )
break;
prev = cur;
}
if ( cur == NULL ) {
Debug( LDAP_DEBUG_ANY, "delmsg: cannot find msg %lx\n",
(unsigned long) m, 0, 0 );
return( -1 );
}
if ( prev == NULL ) {
messages = cur->m_next;
} else {
prev->m_next = cur->m_next;
}
conn_free( cur->m_conn );
modlist_free( cur->m_mods );
ber_free( cur->m_ber, 1 );
#ifdef LDAP_CONNECTIONLESS
if ( cur->m_searchbase != NULLDN ) {
dn_free( cur->m_searchbase );
}
#endif /* LDAP_CONNECTIONLESS */
free( (char *) cur );
return( 0 );
}
/*
* send_msg - Send a messge in response to every outstanding request on
* a given connection. This is used, for example, when an association to
* a dsa fails. It deletes messages to which it responds.
*/
void
send_msg(
struct conn *conn,
Sockbuf *clientsb,
int err,
char *str
)
{
struct msg *tmp, *next;
next = NULL;
for ( tmp = messages; tmp != NULL; tmp = next ) {
next = tmp->m_next;
if ( tmp->m_conn == conn ) {
send_ldap_msgresult( clientsb, tmp->m_msgtype, tmp,
err, NULL, str );
}
del_msg( tmp );
}
}
#ifdef LDAP_CONNECTIONLESS
struct msg *
get_cldap_msg(
int msgid,
int msgtype,
struct sockaddr *fromaddr
)
{
struct msg *tmp;
for ( tmp = messages; tmp != NULL; tmp = tmp->m_next ) {
if ( tmp->m_cldap && tmp->m_msgid == msgid &&
tmp->m_msgtype == msgtype &&
((struct sockaddr_in *)&tmp->m_clientaddr)->sin_port ==
((struct sockaddr_in *)fromaddr)->sin_port &&
((struct sockaddr_in *)&tmp->m_clientaddr)->sin_addr.s_addr
== ((struct sockaddr_in *)fromaddr)->sin_addr.s_addr ) {
break;
}
}
return( tmp );
}
#endif /* LDAP_CONNECTIONLESS */