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

Last change on this file since 10002 was 10002, checked in by Christoph Mayer, 13 years ago

-android fix, does not support getprotobyname

File size: 10.5 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 protlib
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 protlib
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
157#ifdef ANDROID
158 if(strcmp(pname, "tcp") == 0) return tsdb::tcp_id;
159 else if(strcmp(pname, "udp") == 0) return tsdb::udp_id;
160 else if(strcmp(pname, "sctp") == 0) return tsdb::sctp_id;
161 else return 0;
162#endif
163
164 register protocol_t pnum;
165 struct protoent* entry = NULL;
166 if (is_init) {
167 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
168 if (pname) entry = ::getprotobyname(pname);
169 if (res) *res = (entry!=NULL);
170 if (entry) pnum = entry->p_proto;
171 else pnum = 0;
172 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
173 } else {
174 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
175 if (res) *res = false;
176 pnum = 0;
177 } // end if is_init
178 return pnum;
179} // end getprotobyname
180
181string tsdb::get_username(uid_t uid, bool *res) {
182 string str;
183 if (is_init) {
184 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
185 struct passwd* entry = ::getpwuid(uid);
186 if (res) *res = (entry!=NULL);
187 if (entry) str = entry->pw_name;
188 else str = "UNKNOWN";
189 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
190 } else {
191 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
192 if (res) *res = false;
193 str = "";
194 } // end if is_init
195 return str;
196} // end get_username
197
198uid_t tsdb::get_userid(const char* uname, bool *res) {
199 register uid_t uid;
200 struct passwd* entry = NULL;
201 if (is_init) {
202 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
203 if (uname) entry = ::getpwnam(uname);
204 if (res) *res = (entry!=NULL);
205 if (entry) uid = entry->pw_uid;
206 else uid = 0;
207 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
208 } else {
209 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
210 if (res) *res = false;
211 uid = 0;
212 } // end if is_init
213 return uid;
214} // end get_userid
215
216uid_t tsdb::get_userid(const string& uname, bool *res) {
217 return get_userid(uname.c_str(),res);
218} // end get_userid
219
220string tsdb::get_portname(port_t port, protocol_t prot, bool *res) {
221 string str;
222 if (is_init) {
223 bool tmpres = true;
224 string pname = getprotobynumber(prot,&tmpres);
225 if (tmpres) {
226 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
227 struct servent* entry = ::getservbyport(htons(port),pname.c_str());
228 if (res) *res = (entry!=NULL);
229 if (entry) str = entry->s_name;
230 else str = "UNKNOWN";
231 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
232 } else {
233 if (res) *res = false;
234 str = "UNKNOWN";
235 } // end if tmpres
236 } else {
237 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
238 if (res) *res = false;
239 str = "";
240 } // end if is_init
241 return str;
242} // end get_portname
243
244port_t tsdb::get_portnumber(const char* pname, protocol_t prot, bool *res) {
245 register port_t pnum;
246 struct servent* entry = NULL;
247 if (is_init) {
248 bool tmpres = true;
249 string protoname = getprotobynumber(prot,&tmpres);
250 if (tmpres) {
251 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
252 if (pname) entry = ::getservbyname(pname,protoname.c_str());
253 if (res) *res = (entry!=NULL);
254 if (entry) pnum = ntohs(entry->s_port);
255 else pnum = 0;
256 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
257 } else {
258 if (res) *res = false;
259 pnum = 0;
260 } // end if tmpres
261 } else {
262 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
263 if (res) *res = false;
264 pnum = 0;
265 } // end if is_init
266 return pnum;
267} // end get_portnumber
268
269port_t tsdb::get_portnumber(const string& pname, protocol_t prot, bool *res) {
270 return get_portnumber(pname.c_str(),prot,res);
271} // end get_portnumber
272
273
274string
275tsdb::get_hostname(const struct sockaddr* sa, bool *res)
276{
277 string str;
278 static char tmpbuf[NI_MAXHOST];
279
280 if (is_init)
281 {
282 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
283 if (resolvenames)
284 {
285 int resultval= getnameinfo(sa,sizeof(struct sockaddr),
286 tmpbuf,sizeof(tmpbuf),
287 0,0, // services
288 0); // flags
289
290 if (res) *res = (resultval==0);
291 if (resultval==0)
292 { // success
293 str= tmpbuf; // this should copy the buffer contents
294 }
295 else
296 {
297 str = "UNKNOWN";
298 if (resultval==EAI_AGAIN || errno==EAI_AGAIN)
299 {
300 Log(INFO_LOG,LOG_NORMAL, "Threadsafe_DB", "Temporary failure in name lookup. Try again later.");
301 }
302 else
303 Log(INFO_LOG,LOG_NORMAL, "Threadsafe_DB", "Name lookup failed -" << strerror(errno));
304
305 if (res) *res= false;
306 }
307 }
308 else
309 {
310 str= "disabled";
311 if (res) *res= false;
312 }
313 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
314 }
315 else
316 {
317 Log(ERROR_LOG,LOG_NORMAL, "Threadsafe_DB", "Tried to access tsdb although not initialized.");
318 if (res) *res = false;
319 str = "";
320 } // end if is_init
321 return str;
322} // ent get_hostname(in_addr)
323
324
325
326/** lookup of hostname for an ipv4 address
327 * @param in ipv4 address structure
328 * @param res returns true if name lookup was successful, otherwise false
329 *
330 * @return in case that resolving is enabled it returns the host name corresponding to the given address or "UNKNOWN",
331 * otherwise it returns "disabled"
332 */
333string
334tsdb::get_hostname(const in_addr& in, bool *res)
335{
336 struct sockaddr_in sa={
337 AF_INET,
338 0,
339 in
340 };
341 return get_hostname(reinterpret_cast<const sockaddr*>(&sa),res);
342}
343
344/** lookup of hostname for ipv6 address
345 * @param in ipv6 address structure
346 * @param res returns true if name lookup was successful, otherwise false
347 *
348 * @return in case that resolving is enabled it returns the host name corresponding to the given address or "UNKNOWN",
349 * otherwise it returns "disabled"
350 */
351string
352tsdb::get_hostname(const in6_addr& in, bool *res)
353{
354 struct sockaddr_in6 sa={
355 AF_INET6,
356 0, // transport layer port #
357 0, // IPv6 flow information
358 in,
359 0 // scope id (new in RFC2553)
360 };
361 return get_hostname(reinterpret_cast<const sockaddr*>(&sa),res);
362} // ent get_hostname(in6_addr)
363
364//@}
365
366} // end namespace protlib
Note: See TracBrowser for help on using the repository browser.