2626
2727#include < mysql_version.h>
2828
29- #if MYSQL_VERSION_ID>=50515
3029#include " sql_class.h"
3130#include " sql_array.h"
32- #elif MYSQL_VERSION_ID>50100
33- #include " mysql_priv.h"
34- #include < mysql/plugin.h>
35- #else
36- #include " ../mysql_priv.h"
37- #endif
3831
3932#include < mysys_err.h>
4033#include < my_sys.h>
4134
42- #if MYSQL_VERSION_ID>=50120
4335typedef uchar byte;
44- #endif
4536
4637// / partially copy-pasted stuff that should be moved elsewhere
4738
@@ -90,7 +81,6 @@ void sphUnalignedWrite ( void * pPtr, const T & tVal )
9081#define SafeDelete (_arg ) { if ( _arg ) delete ( _arg ); (_arg) = NULL ; }
9182#define SafeDeleteArray (_arg ) { if ( _arg ) delete [] ( _arg ); (_arg) = NULL ; }
9283
93- #define Min (a,b ) ((a)<(b)?(a):(b))
9484#ifndef _WIN32
9585typedef unsigned int DWORD;
9686#endif
@@ -360,82 +350,68 @@ bool CSphUrl::Parse ( const char * sUrl, int iLen )
360350
361351int CSphUrl::Connect ()
362352{
363- struct sockaddr_in sin;
364- #ifndef _WIN32
365- struct sockaddr_un saun;
366- #endif
367-
368- int iDomain = 0 ;
369- int iSockaddrSize = 0 ;
370- struct sockaddr * pSockaddr = NULL ;
371-
372- in_addr_t ip_addr;
353+ int iSocket = -1 ;
373354
374355 if ( m_iPort )
375356 {
376- iDomain = AF_INET ;
377- iSockaddrSize = sizeof (sin) ;
378- pSockaddr = ( struct sockaddr *) &sin ;
357+ char portStr[ 16 ] ;
358+ struct addrinfo hints, *hp, *p ;
359+ int tmp_errno ;
379360
380- memset ( &sin, 0 , sizeof (sin) );
381- sin.sin_family = AF_INET;
382- sin.sin_port = htons ( m_iPort );
361+ my_snprintf (portStr, sizeof (portStr), " %d" , m_iPort);
383362
384- // resolve address
385- if ( (int )( ip_addr = inet_addr ( m_sHost ) )!=(int )INADDR_NONE )
386- memcpy ( &sin.sin_addr , &ip_addr, sizeof (ip_addr) );
387- else
363+ memset (&hints, 0 , sizeof (hints));
364+ hints.ai_family = AF_UNSPEC;
365+ hints.ai_socktype = SOCK_STREAM;
366+
367+ tmp_errno = getaddrinfo ( m_sHost, portStr, &hints, &hp );
368+ if ( tmp_errno!=0 || !hp || !hp->ai_addr )
388369 {
389- int tmp_errno;
390- bool bError = false ;
370+ char sError [256 ];
371+ my_snprintf ( sError , sizeof (sError ),
372+ " failed to resolve searchd host (name=%s) because %s" ,
373+ m_sHost, gai_strerror (tmp_errno) );
391374
392- #if MYSQL_VERSION_ID>=50515
393- struct addrinfo *hp = NULL ;
394- tmp_errno = getaddrinfo ( m_sHost, NULL , NULL , &hp );
395- if ( !tmp_errno || !hp || !hp->ai_addr )
396- {
397- bError = true ;
398- if ( hp )
399- freeaddrinfo ( hp );
400- }
401- #else
402- struct hostent tmp_hostent, *hp;
403- char buff2 [ GETHOSTBYNAME_BUFF_SIZE ];
404- hp = my_gethostbyname_r ( m_sHost, &tmp_hostent, buff2, sizeof (buff2), &tmp_errno );
405- if ( !hp )
406- {
407- my_gethostbyname_r_free ();
408- bError = true ;
409- }
410- #endif
375+ my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF (0 ), sError );
376+ return -1 ;
377+ }
411378
412- if ( bError )
413- {
414- char sError [256 ];
415- my_snprintf ( sError , sizeof (sError ), " failed to resolve searchd host (name=%s)" , m_sHost );
379+ for (p = hp; p != NULL ; p = p->ai_next )
380+ {
381+ iSocket = socket (p->ai_family , p->ai_socktype , p->ai_protocol );
382+ if (iSocket == -1 )
383+ continue ;
416384
417- my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF (0 ), sError );
418- return -1 ;
419- }
385+ if (connect (iSocket, p->ai_addr , p->ai_addrlen ) == 0 )
386+ break ; // success
420387
421- #if MYSQL_VERSION_ID>=50515
422- memcpy ( &sin.sin_addr , hp->ai_addr , Min ( sizeof (sin.sin_addr ), (size_t )hp->ai_addrlen ) );
423- freeaddrinfo ( hp );
424- #else
425- memcpy ( &sin.sin_addr , hp->h_addr , Min ( sizeof (sin.sin_addr ), (size_t )hp->h_length ) );
426- my_gethostbyname_r_free ();
427- #endif
388+ close (iSocket);
389+ iSocket = -2 ;
428390 }
391+ freeaddrinfo ( hp );
429392 } else
430393 {
431394#ifndef _WIN32
432- iDomain = AF_UNIX;
433- iSockaddrSize = sizeof (saun);
434- pSockaddr = (struct sockaddr *) &saun;
435-
395+ struct sockaddr_un saun;
436396 memset ( &saun, 0 , sizeof (saun) );
437397 saun.sun_family = AF_UNIX;
398+
399+ if (strlen (m_sHost) >= sizeof (saun.sun_path ))
400+ {
401+ my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF (0 ), " Unix socket path too long" );
402+ return -1 ;
403+ }
438404 strncpy ( saun.sun_path , m_sHost, sizeof (saun.sun_path )-1 );
405+
406+ iSocket = socket (AF_UNIX, SOCK_STREAM, 0 );
407+ if (iSocket >= 0 )
408+ {
409+ if (connect (iSocket, (struct sockaddr *)&saun, sizeof (saun)) == -1 )
410+ {
411+ close (iSocket);
412+ iSocket = -2 ;
413+ }
414+ }
439415#else
440416 my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF (0 ), " Unix-domain sockets are not supported on Windows" );
441417 return -1 ;
@@ -445,36 +421,17 @@ int CSphUrl::Connect()
445421 // connect to searchd and exchange versions
446422 uint uServerVersion;
447423 uint uClientVersion = htonl ( SPHINX_SEARCHD_PROTO );
448- int iSocket = -1 ;
449424 const char * pError = NULL ;
450- do
451- {
452- iSocket = (int )socket ( iDomain, SOCK_STREAM, 0 );
453- if ( iSocket==-1 )
454- {
455- pError = " Failed to create client socket" ;
456- break ;
457- }
425+ if ( iSocket == -1 )
426+ pError = " Failed to create client socket" ;
427+ else if ( iSocket == -2 )
428+ pError = " Failed to connect to searchd" ;
458429
459- if ( connect ( iSocket, pSockaddr, iSockaddrSize )==-1 )
460- {
461- pError = " Failed to connect to searchd" ;
462- break ;
463- }
464-
465- if ( !sphRecv ( iSocket, (char *)&uServerVersion, sizeof (uServerVersion) ) )
466- {
467- pError = " Failed to receive searchd version" ;
468- break ;
469- }
430+ else if ( !sphRecv ( iSocket, (char *)&uServerVersion, sizeof (uServerVersion) ) )
431+ pError = " Failed to receive searchd version" ;
470432
471- if ( !sphSend ( iSocket, (char *)&uClientVersion, sizeof (uClientVersion) ) )
472- {
473- pError = " Failed to send client version" ;
474- break ;
475- }
476- }
477- while (0 );
433+ else if ( !sphSend ( iSocket, (char *)&uClientVersion, sizeof (uClientVersion) ) )
434+ pError = " Failed to send client version" ;
478435
479436 // fixme: compare versions?
480437
@@ -484,8 +441,8 @@ int CSphUrl::Connect()
484441 snprintf ( sError , sizeof (sError ), " %s [%d] %s" , Format (), errno, strerror (errno) );
485442 my_error ( ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF (0 ), sError );
486443
487- if ( iSocket!=- 1 )
488- close ( iSocket );
444+ if ( iSocket >= 0 )
445+ close ( iSocket);
489446
490447 return -1 ;
491448 }
0 commit comments