Lines 278-367
Link Here
|
278 |
|
278 |
|
279 |
int Connection::DoConnect() |
279 |
int Connection::DoConnect() |
280 |
{ |
280 |
{ |
281 |
debug("Do connecting"); |
281 |
debug("Do connecting"); |
282 |
|
282 |
|
283 |
struct sockaddr_in sSocketAddress; |
283 |
int res; |
284 |
memset(&sSocketAddress, '\0', sizeof(sSocketAddress)); |
|
|
285 |
sSocketAddress.sin_family = AF_INET; |
286 |
sSocketAddress.sin_port = htons(m_pNetAddress->GetPort()); |
287 |
sSocketAddress.sin_addr.s_addr = ResolveHostAddr(m_pNetAddress->GetHost()); |
288 |
if (sSocketAddress.sin_addr.s_addr == (unsigned int)-1) |
289 |
{ |
290 |
return -1; |
291 |
} |
292 |
|
284 |
|
293 |
m_iSocket = socket(PF_INET, SOCK_STREAM, 0); |
285 |
struct addrinfo addr_hints, *addr_list, *addr; |
|
|
286 |
char iPortStr[sizeof(int) * 4 + 1]; //is enough to hold any converted int |
294 |
|
287 |
|
295 |
if (m_iSocket == INVALID_SOCKET) |
288 |
memset(&addr_hints, 0, sizeof(addr_hints)); |
296 |
{ |
289 |
addr_hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ |
297 |
ReportError("Socket creation failed for %s!", m_pNetAddress->GetHost(), 0); |
290 |
addr_hints.ai_socktype = SOCK_STREAM, |
298 |
return -1; |
|
|
299 |
} |
300 |
|
291 |
|
301 |
int res = connect(m_iSocket , (struct sockaddr *) & sSocketAddress, sizeof(sSocketAddress)); |
292 |
sprintf(iPortStr, "%d", m_pNetAddress->GetPort()); |
302 |
|
293 |
|
303 |
if (res < 0) |
294 |
res = ::getaddrinfo( m_pNetAddress->GetHost(), iPortStr, &addr_hints, &addr_list ); |
304 |
{ |
|
|
305 |
ReportError("Connection to %s failed!", m_pNetAddress->GetHost(), 0); |
306 |
return -1; |
307 |
} |
308 |
|
295 |
|
309 |
#ifdef WIN32 |
296 |
if( res != 0 ) |
310 |
int MSecVal = m_iTimeout * 1000; |
297 |
{ |
311 |
int err = setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&MSecVal, sizeof(MSecVal)); |
298 |
error("Could not resolve hostname %s", m_pNetAddress->GetHost()); |
312 |
#else |
299 |
return -1; |
313 |
struct timeval TimeVal; |
300 |
} |
314 |
TimeVal.tv_sec = m_iTimeout; |
|
|
315 |
TimeVal.tv_usec = 0; |
316 |
int err = setsockopt(m_iSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&TimeVal, sizeof(TimeVal)); |
317 |
#endif |
318 |
if (err != 0) |
319 |
{ |
320 |
ReportError("setsockopt failed", NULL, 0); |
321 |
} |
322 |
|
301 |
|
323 |
return 0; |
302 |
for (addr = addr_list; addr != NULL; addr = addr->ai_next) |
324 |
} |
303 |
{ |
|
|
304 |
m_iSocket = ::socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); |
305 |
if (m_iSocket == -1) continue; |
325 |
|
306 |
|
326 |
unsigned int Connection::ResolveHostAddr(const char* szHost) |
307 |
res = ::connect( m_iSocket , addr->ai_addr, addr->ai_addrlen ); |
327 |
{ |
308 |
if (res != -1) break; /* Connection established */ |
328 |
unsigned int uaddr = inet_addr(szHost); |
309 |
} |
329 |
if (uaddr == (unsigned int)-1) |
|
|
330 |
{ |
331 |
struct hostent* hinfo; |
332 |
bool err = false; |
333 |
int h_errnop = 0; |
334 |
#ifdef WIN32 |
335 |
hinfo = gethostbyname(szHost); |
336 |
err = hinfo == NULL; |
337 |
h_errnop = WSAGetLastError(); |
338 |
#else |
339 |
struct hostent hinfobuf; |
340 |
static const int strbuflen = 1024; |
341 |
char* strbuf = (char*)malloc(strbuflen); |
342 |
#ifdef HAVE_GETHOSTBYNAME_R_6 |
343 |
err = gethostbyname_r(szHost, &hinfobuf, strbuf, strbuflen, &hinfo, &h_errnop); |
344 |
err = err || (hinfo == NULL); // error on null hinfo (means 'no entry') |
345 |
#else |
346 |
hinfo = gethostbyname_r(szHost, &hinfobuf, strbuf, strbuflen, &h_errnop); |
347 |
err = hinfo == NULL; |
348 |
#endif |
349 |
#endif |
350 |
if (err) |
351 |
{ |
352 |
ReportError("Could not resolve hostname %s", szHost, h_errnop); |
353 |
#ifndef WIN32 |
354 |
free(strbuf); |
355 |
#endif |
356 |
return (unsigned int)-1; |
357 |
} |
358 |
|
310 |
|
359 |
memcpy(&uaddr, hinfo->h_addr_list[0], sizeof(uaddr)); |
311 |
if( addr == NULL ) |
360 |
#ifndef WIN32 |
312 |
{ |
361 |
free(strbuf); |
313 |
error("Socket creation or connection failed for %s!", m_pNetAddress->GetHost()); |
362 |
#endif |
314 |
return -1; |
363 |
} |
315 |
} |
364 |
return uaddr; |
316 |
|
|
|
317 |
freeaddrinfo( addr_list ); /* No longer needed */ |
318 |
|
319 |
return 0; |
365 |
} |
320 |
} |
366 |
|
321 |
|
367 |
int Connection::DoDisconnect() |
322 |
int Connection::DoDisconnect() |
Lines 459-495
Link Here
|
459 |
{ |
414 |
{ |
460 |
debug("Do binding"); |
415 |
debug("Do binding"); |
461 |
|
416 |
|
462 |
m_iSocket = socket(PF_INET, SOCK_STREAM, 0); |
417 |
int res; |
463 |
if (m_iSocket == INVALID_SOCKET) |
|
|
464 |
{ |
465 |
ReportError("Socket creation failed for %s!", m_pNetAddress->GetHost(), 0); |
466 |
return -1; |
467 |
} |
468 |
|
418 |
|
469 |
struct sockaddr_in sSocketAddress; |
419 |
struct addrinfo addr_hints, *addr_list, *addr; |
470 |
memset(&sSocketAddress, '\0', sizeof(sSocketAddress)); |
420 |
char iPortStr[sizeof(int) * 4 + 1]; //is enough to hold any converted int |
471 |
sSocketAddress.sin_family = AF_INET; |
421 |
|
472 |
if (!m_pNetAddress->GetHost() || strlen(m_pNetAddress->GetHost()) == 0) |
422 |
memset(&addr_hints, 0, sizeof(addr_hints)); |
473 |
{ |
423 |
addr_hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ |
474 |
sSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY); |
424 |
addr_hints.ai_socktype = SOCK_STREAM, |
475 |
} |
425 |
addr_hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ |
476 |
else |
426 |
|
477 |
{ |
427 |
sprintf(iPortStr, "%d", m_pNetAddress->GetPort()); |
478 |
sSocketAddress.sin_addr.s_addr = ResolveHostAddr(m_pNetAddress->GetHost()); |
428 |
|
479 |
if (sSocketAddress.sin_addr.s_addr == (unsigned int)-1) |
429 |
res = ::getaddrinfo( m_pNetAddress->GetHost(), iPortStr, &addr_hints, &addr_list ); |
480 |
{ |
430 |
|
481 |
return -1; |
431 |
if( res != 0 ) |
482 |
} |
432 |
{ |
483 |
} |
433 |
error( "Could not resolve hostname %s", m_pNetAddress->GetHost() ); |
484 |
sSocketAddress.sin_port = htons(m_pNetAddress->GetPort()); |
434 |
return -1; |
|
|
435 |
} |
436 |
|
437 |
for (addr = addr_list; addr != NULL; addr = addr->ai_next) |
438 |
{ |
439 |
m_iSocket = ::socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); |
440 |
if (m_iSocket == -1) continue; |
485 |
int opt = 1; |
441 |
int opt = 1; |
486 |
setsockopt(m_iSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)); |
442 |
setsockopt(m_iSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)); |
|
|
443 |
res = ::bind( m_iSocket , addr->ai_addr, addr->ai_addrlen ); |
444 |
if (res != -1) break; /* Connection established */ |
445 |
} |
446 |
|
447 |
if( addr == NULL ) |
448 |
{ |
449 |
error("Socket creation or binding failed for %s!", m_pNetAddress->GetHost() ); |
450 |
return -1; |
451 |
} |
487 |
|
452 |
|
488 |
if (bind(m_iSocket, (struct sockaddr *) &sSocketAddress, sizeof(sSocketAddress)) < 0) |
|
|
489 |
{ |
490 |
ReportError("Binding socket failed for %s", m_pNetAddress->GetHost(), 0); |
491 |
return -1; |
492 |
} |
493 |
|
453 |
|
494 |
if (listen(m_iSocket, 10) < 0) |
454 |
if (listen(m_iSocket, 10) < 0) |
495 |
{ |
455 |
{ |