source: source/ariba/communication/modules/transport/protlib/threadsafe_db.cpp@ 5638

Last change on this file since 5638 was 5638, checked in by Christoph Mayer, 15 years ago

adress detection aufgeräumt, network info für bleutooth, data stream (hopeful crash fix), logging auf maemo nur warn, ...

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.