|
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 |
{ |