/* This file is part of actube. actube is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. libcapwap is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . */ #include #include #include #include #include #include #include #include "conn.h" #include "connlist.h" #include "sock.h" #include "dbg.h" static int cmp_by_addr_p ( const void * d1, const void *d2 ) { struct cw_Conn * c1 = * ( void ** ) d1 ; struct cw_Conn * c2 = * ( void ** ) d2 ; return sock_cmpaddr ( ( struct sockaddr* ) &c1->addr, ( struct sockaddr* ) &c2->addr, 1 ); } static int cmp_by_addr ( const void * d1, const void *d2 ) { struct cw_Conn * c1 = * ( void ** ) d1 ; struct cw_Conn * c2 = * ( void ** ) d2 ; return sock_cmpaddr ( ( struct sockaddr* ) &c1->addr, ( struct sockaddr* ) &c2->addr, 0 ); } static int cmp_by_session_id ( const void *d1, const void *d2 ) { struct cw_Conn * c1 = *( void ** ) d1; struct cw_Conn * c2 = *( void ** ) d2; int len1,len2; if (c1->session_id==NULL && c2->session_id==NULL) return 0; if (c1->session_id==NULL) return -1; if (c2->session_id==NULL) return 1; len1 = bstr16_len(c1->session_id); len2 = bstr16_len(c2->session_id); if (len1 != len2 ) return len1-len2; return memcmp ( bstr16_data(c1->session_id), bstr16_data(c2->session_id), len1 ); } /** * @brief Create a connection list * @param len initial length * @param cmpports compare ports * @return the create connection list or NULL if an error has occured. */ struct connlist * connlist_create ( int len, int cmpports ) { struct connlist * cl = malloc ( sizeof ( struct connlist ) ); if ( !cl ) return 0; if (cmpports){ cl->by_addr = mavl_create_ptr ( cmp_by_addr_p, NULL ); } else{ cl->by_addr = mavl_create_ptr ( cmp_by_addr, NULL ); } if ( !cl->by_addr ) { free ( cl ); return 0; } cl->by_session_id = mavl_create_ptr ( cmp_by_session_id, NULL ); if ( pthread_mutex_init ( &cl->connlist_mutex, NULL ) ) { mavl_destroy ( cl->by_addr ); free ( cl ); return 0; }; cl->len = len; return cl; } void connlist_lock ( struct connlist * cl ) { pthread_mutex_lock ( &cl->connlist_mutex ); } void connlist_unlock ( struct connlist * cl ) { pthread_mutex_unlock ( &cl->connlist_mutex ); } void connlist_destroy ( struct connlist * cl ) { if ( !cl ) return; if ( cl->by_addr ) mavl_destroy ( cl->by_addr ); if ( cl->by_session_id) mavl_destroy ( cl->by_session_id ); pthread_mutex_destroy ( &cl->connlist_mutex ); free ( cl ); } struct cw_Conn * connlist_get ( struct connlist * cl, const struct sockaddr * addr ) { struct cw_Conn search; sock_copyaddr ( &search.addr, addr ); return mavl_get_ptr ( cl->by_addr, &search ); } struct cw_Conn * connlist_add ( struct connlist * cl, struct cw_Conn * conn ) { if ( cl->len != 0 ) if ( cl->by_addr->count >= cl->len ) return NULL; conn->connlist = cl; return mavl_insert_ptr ( cl->by_addr, conn ); } struct cw_Conn * connlist_get_by_session_id ( struct connlist *cl, struct cw_Conn * conn ) { return mavl_get_ptr ( cl->by_session_id, conn ); } struct cw_Conn * connlist_add_by_session_id ( struct connlist * cl, struct cw_Conn * conn ) { return mavl_insert_ptr ( cl->by_session_id, conn ); } void connlist_remove ( struct connlist *cl, struct cw_Conn * conn ) { void * md; md = conn; mavl_del ( cl->by_session_id, &md ); md = conn; mavl_del ( cl->by_addr, &md ); }