mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-15 03:01:09 +08:00
176 lines
3.7 KiB
C
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 */
|