source: source/ariba/utility/transport/tcpip/protlib/threadsafe_db.cpp@ 5424

Last change on this file since 5424 was 5284, checked in by mies, 15 years ago

+ added new transport modules and adapted ariba to them
+ exchange endpoint descriptors an link establishment
+ clean up of base communication
+ link establishment with in the presence of multiple endpoints
+ local discovery for ipv6, ipv4 and bluetooth mac addresses

File size: 10.3 KB
Line 
1/// ----------------------------------------*- mode: C++; -*--
2/// @file threadsafe_db.cpp
3/// Thread-safe access for some resolving functions (netdb)...
4/// ----------------------------------------------------------
5/// $Id: threadsafe_db.cpp 2872 2008-02-18 10:58:03Z bless $
6/// $HeadURL: https://svn.ipv6.tm.uka.de/nsis/protlib/trunk/src/threadsafe_db.cpp $
7// ===========================================================
8//
9// Copyright (C) 2005-2007, all rights reserved by
10// - Institute of Telematics, Universitaet Karlsruhe (TH)
11//
12// More information and contact:
13// https://projekte.tm.uka.de/trac/NSIS
14//
15// This program is free software; you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation; version 2 of the License
18//
19// This program is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22// GNU General Public License for more details.
23//
24// You should have received a copy of the GNU General Public License along
25// with this program; if not, write to the Free Software Foundation, Inc.,
26// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27//
28// ===========================================================
29/** @ingroup netdb
30 *
31 * As the reentrant functions for netdb access seem not portable, I decided to
32 * write some wrappers for those functions I need. This is not
33 * object-oriented because the NetDB would be another singleton object and
34 * I only want some wrapper functions.
35 */
36
37#include <netdb.h>
38#include <pwd.h>
39#include <netinet/in.h>
40#include <cerrno>
41
42#include "threadsafe_db.h"
43#include "cleanuphandler.h"
44#include "logfile.h"
45
46namespace protlib {
47
48/** @addtogroup netdb Thread-safe DB
49 * @{
50 */
51
52 using namespace log;
53
54bool tsdb::is_init = false;
55bool tsdb::resolvenames = true;
56pthread_mutex_t tsdb::mutex =
57#ifdef _DEBUG
58 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
59#else
60 PTHREAD_MUTEX_INITIALIZER;
61#endif
62
63
64uint32 tsdb::id32 = 1;
65uint64 tsdb::id64 = 1;
66
67protocol_t tsdb::udp_id= 17;
68protocol_t tsdb::tcp_id= 6;
69protocol_t tsdb::sctp_id= 132;
70
71
72void
73tsdb::init(bool noresolving)
74{
75 if (is_init)
76 {
77 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to initialize tstdb although already initialized.");
78 } else
79 {
80 pthread_mutex_init(&mutex,NULL);
81 is_init = true;
82
83 // initialize frequently used protocol constants
84 udp_id= tsdb::getprotobyname("udp");
85 tcp_id= tsdb::getprotobyname("tcp");
86 sctp_id= tsdb::getprotobyname("sctp");
87
88 resolvenames=!noresolving;
89 if (!resolvenames)
90 Log(INFO_LOG,LOG_NORMAL,"Threadsafe_DB"," ** Disabled reverse name lookups - addresses will not be resolved to names **");
91 } // end if is_init
92} // end init
93
94void tsdb::end() {
95 if (is_init) {
96 is_init = false;
97 pthread_mutex_destroy(&mutex);
98 } else {
99 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to end tstdb although not initialized.");
100 } // end if is_init
101} // end end
102
103uint32 tsdb::get_new_id32() {
104 uint32 res = 0;
105 if (is_init) {
106 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
107 res = id32++;
108 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
109 } else {
110 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
111 } // end if is_init
112 return res;
113} // end get_new_id32
114
115uint64 tsdb::get_new_id64() {
116 uint64 res = 0;
117 if (is_init) {
118 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
119 res = id64++;
120 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
121 } else {
122 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
123 } // end if is_init
124 return res;
125} // end get_new_id64
126
127string tsdb::getprotobynumber(protocol_t proto, bool *res) {
128 string str;
129 if (is_init)
130 {
131 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
132 struct protoent* entry = ::getprotobynumber(proto);
133
134 if (res) *res = (entry!=NULL);
135 if (entry)
136 str = entry->p_name;
137 else
138 str = "UNKNOWN";
139
140 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
141 }
142 else
143 {
144 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
145 if (res) *res = false;
146 str = "";
147 } // end if is_init
148 return str;
149} // end getprotobynumber
150
151protocol_t tsdb::getprotobyname(const string &pname, bool *res) {
152 return getprotobyname(pname.c_str(),res);
153} // end getprotobyname
154
155protocol_t tsdb::getprotobyname(const char* pname, bool *res) {
156 register protocol_t pnum;
157 struct protoent* entry = NULL;
158 if (is_init) {
159 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
160 if (pname) entry = ::getprotobyname(pname);
161 if (res) *res = (entry!=NULL);
162 if (entry) pnum = entry->p_proto;
163 else pnum = 0;
164 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
165 } else {
166 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
167 if (res) *res = false;
168 pnum = 0;
169 } // end if is_init
170 return pnum;
171} // end getprotobyname
172
173string tsdb::get_username(uid_t uid, bool *res) {
174 string str;
175 if (is_init) {
176 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
177 struct passwd* entry = ::getpwuid(uid);
178 if (res) *res = (entry!=NULL);
179 if (entry) str = entry->pw_name;
180 else str = "UNKNOWN";
181 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
182 } else {
183 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
184 if (res) *res = false;
185 str = "";
186 } // end if is_init
187 return str;
188} // end get_username
189
190uid_t tsdb::get_userid(const char* uname, bool *res) {
191 register uid_t uid;
192 struct passwd* entry = NULL;
193 if (is_init) {
194 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
195 if (uname) entry = ::getpwnam(uname);
196 if (res) *res = (entry!=NULL);
197 if (entry) uid = entry->pw_uid;
198 else uid = 0;
199 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
200 } else {
201 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
202 if (res) *res = false;
203 uid = 0;
204 } // end if is_init
205 return uid;
206} // end get_userid
207
208uid_t tsdb::get_userid(const string& uname, bool *res) {
209 return get_userid(uname.c_str(),res);
210} // end get_userid
211
212string tsdb::get_portname(port_t port, protocol_t prot, bool *res) {
213 string str;
214 if (is_init) {
215 bool tmpres = true;
216 string pname = getprotobynumber(prot,&tmpres);
217 if (tmpres) {
218 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
219 struct servent* entry = ::getservbyport(htons(port),pname.c_str());
220 if (res) *res = (entry!=NULL);
221 if (entry) str = entry->s_name;
222 else str = "UNKNOWN";
223 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
224 } else {
225 if (res) *res = false;
226 str = "UNKNOWN";
227 } // end if tmpres
228 } else {
229 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
230 if (res) *res = false;
231 str = "";
232 } // end if is_init
233 return str;
234} // end get_portname
235
236port_t tsdb::get_portnumber(const char* pname, protocol_t prot, bool *res) {
237 register port_t pnum;
238 struct servent* entry = NULL;
239 if (is_init) {
240 bool tmpres = true;
241 string protoname = getprotobynumber(prot,&tmpres);
242 if (tmpres) {
243 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
244 if (pname) entry = ::getservbyname(pname,protoname.c_str());
245 if (res) *res = (entry!=NULL);
246 if (entry) pnum = ntohs(entry->s_port);
247 else pnum = 0;
248 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
249 } else {
250 if (res) *res = false;
251 pnum = 0;
252 } // end if tmpres
253 } else {
254 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
255 if (res) *res = false;
256 pnum = 0;
257 } // end if is_init
258 return pnum;
259} // end get_portnumber
260
261port_t tsdb::get_portnumber(const string& pname, protocol_t prot, bool *res) {
262 return get_portnumber(pname.c_str(),prot,res);
263} // end get_portnumber
264
265
266string
267tsdb::get_hostname(const struct sockaddr* sa, bool *res)
268{
269 string str;
270 static char tmpbuf[NI_MAXHOST];
271
272 if (is_init)
273 {
274 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
275 if (resolvenames)
276 {
277 int resultval= getnameinfo(sa,sizeof(struct sockaddr),
278 tmpbuf,sizeof(tmpbuf),
279 0,0, // services
280 0); // flags
281
282 if (res) *res = (resultval==0);
283 if (resultval==0)
284 { // success
285 str= tmpbuf; // this should copy the buffer contents
286 }
287 else
288 {
289 str = "UNKNOWN";
290 if (resultval==EAI_AGAIN || errno==EAI_AGAIN)
291 {
292 Log(INFO_LOG,LOG_NORMAL, "Threadsafe_DB", "Temporary failure in name lookup. Try again later.");
293 }
294 else
295 Log(INFO_LOG,LOG_NORMAL, "Threadsafe_DB", "Name lookup failed -" << strerror(errno));
296
297 if (res) *res= false;
298 }
299 }
300 else
301 {
302 str= "disabled";
303 if (res) *res= false;
304 }
305 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
306 }
307 else
308 {
309 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
310 if (res) *res = false;
311 str = "";
312 } // end if is_init
313 return str;
314} // ent get_hostname(in_addr)
315
316
317
318/** lookup of hostname for an ipv4 address
319 * @param in ipv4 address structure
320 * @param res returns true if name lookup was successful, otherwise false
321 *
322 * @return in case that resolving is enabled it returns the host name corresponding to the given address or "UNKNOWN",
323 * otherwise it returns "disabled"
324 */
325string
326tsdb::get_hostname(const in_addr& in, bool *res)
327{
328 struct sockaddr_in sa={
329 AF_INET,
330 0,
331 in
332 };
333 return get_hostname(reinterpret_cast<const sockaddr*>(&sa),res);
334}
335
336/** lookup of hostname for ipv6 address
337 * @param in ipv6 address structure
338 * @param res returns true if name lookup was successful, otherwise false
339 *
340 * @return in case that resolving is enabled it returns the host name corresponding to the given address or "UNKNOWN",
341 * otherwise it returns "disabled"
342 */
343string
344tsdb::get_hostname(const in6_addr& in, bool *res)
345{
346 struct sockaddr_in6 sa={
347 AF_INET6,
348 0, // transport layer port #
349 0, // IPv6 flow information
350 in,
351 0 // scope id (new in RFC2553)
352 };
353 return get_hostname(reinterpret_cast<const sockaddr*>(&sa),res);
354} // ent get_hostname(in6_addr)
355
356//@}
357
358} // end namespace protlib
Note: See TracBrowser for help on using the repository browser.