/* * 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 #include #include #include #include #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 */