Fixed error messages not being printed and cleaned up the function.

This commit is contained in:
Markus Makela
2015-09-17 07:13:24 +03:00
parent 561891aac5
commit 988a8d7008

View File

@ -1331,164 +1331,186 @@ return_1:
} }
/** /**
* set listener for mysql protocol, retur 1 on success and 0 in failure * Bind the DCB to a network port or a UNIX Domain Socket.
* @param listen_dcb Listener DCB
* @param config_bind Bind address in either IP:PORT format for network sockets or PATH for UNIX Domain Sockets
* @return 1 on success, 0 on error
*/ */
int gw_MySQLListener( int gw_MySQLListener(DCB *listen_dcb,
DCB *listen_dcb, char *config_bind)
char *config_bind)
{ {
int l_so; int l_so;
int syseno = 0; struct sockaddr_in serv_addr;
struct sockaddr_in serv_addr; struct sockaddr_un local_addr;
struct sockaddr_un local_addr; struct sockaddr *current_addr;
struct sockaddr *current_addr; int one = 1;
int one = 1; int rc;
int rc; bool is_tcp = false;
bool is_tcp = false; memset(&serv_addr, 0, sizeof (serv_addr));
memset(&serv_addr,0,sizeof(serv_addr)); memset(&local_addr, 0, sizeof (local_addr));
memset(&local_addr,0,sizeof(local_addr));
if (strchr(config_bind, '/')) { if (strchr(config_bind, '/'))
char *tmp = strrchr(config_bind, ':'); {
if (tmp) char *tmp = strrchr(config_bind, ':');
*tmp = '\0'; if (tmp)
*tmp = '\0';
// UNIX socket create // UNIX socket create
if ((l_so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { if ((l_so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
char errbuf[STRERROR_BUFLEN]; {
fprintf(stderr,
"\n* Error: can't create UNIX socket due "
"error %i, %s.\n\n\t",
errno,
strerror_r(errno, errbuf, sizeof(errbuf)));
return 0;
}
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sun_family = AF_UNIX;
strncpy(local_addr.sun_path, config_bind, sizeof(local_addr.sun_path) - 1);
current_addr = (struct sockaddr *) &local_addr;
} else {
/* MaxScale, as default, will bind on port 4406 */
if (!parse_bindconfig(config_bind, 4406, &serv_addr)) {
fprintf(stderr, "Error in parse_bindconfig for [%s]\n", config_bind);
return 0;
}
// TCP socket create
if ((l_so = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
char errbuf[STRERROR_BUFLEN];
fprintf(stderr,
"\n* Error: can't create socket due "
"error %i, %s.\n\n\t",
errno,
strerror_r(errno, errbuf, sizeof(errbuf)));
return 0;
}
current_addr = (struct sockaddr *) &serv_addr;
is_tcp = true;
}
listen_dcb->fd = -1;
// socket options
if((syseno = setsockopt(l_so, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))) != 0){
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf)))));
}
if(is_tcp)
{
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
if((syseno = setsockopt(l_so, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one))) != 0){ skygw_log_write(LE,
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))))); "Error: Can't create UNIX socket: %i, %s",
} errno,
} strerror_r(errno, errbuf, sizeof (errbuf)));
// set NONBLOCKING mode return 0;
setnonblocking(l_so); }
memset(&local_addr, 0, sizeof (local_addr));
local_addr.sun_family = AF_UNIX;
strncpy(local_addr.sun_path, config_bind, sizeof (local_addr.sun_path) - 1);
/* get the right socket family for bind */ current_addr = (struct sockaddr *) &local_addr;
switch (current_addr->sa_family) {
case AF_UNIX:
rc = unlink(config_bind);
if ( (rc == -1) && (errno!=ENOENT) ) {
fprintf(stderr, "Error unlink Unix Socket %s\n", config_bind);
}
if (bind(l_so, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0) { }
char errbuf[STRERROR_BUFLEN]; else
fprintf(stderr, {
"\n* Bind failed due error %i, %s.\n", /* This is partially dead code, MaxScale will never start without explicit
errno, * ports defined for all listeners. Thus the default port is never used.
strerror_r(errno, errbuf, sizeof(errbuf))); */
fprintf(stderr, "* Can't bind to %s\n\n", config_bind); if (!parse_bindconfig(config_bind, 4406, &serv_addr))
close(l_so); {
return 0; skygw_log_write(LE, "Error in parse_bindconfig for [%s]", config_bind);
} return 0;
}
/* set permission for all users */ /** Create the TCP socket */
if (chmod(config_bind, 0777) < 0) { if ((l_so = socket(AF_INET, SOCK_STREAM, 0)) < 0)
char errbuf[STRERROR_BUFLEN]; {
fprintf(stderr, char errbuf[STRERROR_BUFLEN];
"\n* chmod failed for %s due error %i, %s.\n\n", skygw_log_write(LE,
config_bind, "Error: Can't create socket: %i, %s",
errno, errno,
strerror_r(errno, errbuf, sizeof(errbuf))); strerror_r(errno, errbuf, sizeof (errbuf)));
} return 0;
}
break; current_addr = (struct sockaddr *) &serv_addr;
is_tcp = true;
}
case AF_INET: listen_dcb->fd = -1;
if (bind(l_so, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
char errbuf[STRERROR_BUFLEN];
fprintf(stderr,
"\n* Bind failed due error %i, %s.\n",
errno,
strerror_r(errno, errbuf, sizeof(errbuf)));
fprintf(stderr, "* Can't bind to %s\n\n", config_bind);
close(l_so);
return 0;
}
break;
default: // socket options
fprintf(stderr, "* Socket Family %i not supported\n", current_addr->sa_family); if (setsockopt(l_so, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (one)) != 0)
close(l_so); {
return 0; char errbuf[STRERROR_BUFLEN];
} LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof (errbuf)))));
}
rc = listen(l_so, 10 * SOMAXCONN); if (is_tcp)
{
char errbuf[STRERROR_BUFLEN];
if (setsockopt(l_so, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof (one)) != 0)
{
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof (errbuf)))));
}
}
// set NONBLOCKING mode
if (setnonblocking(l_so) != 0)
{
skygw_log_write(LE, "Error: Failed to set socket to non-blocking mode.");
close(l_so);
return 0;
}
if (rc == 0) { /* get the right socket family for bind */
LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE,"Listening MySQL connections at %s", config_bind))); switch (current_addr->sa_family)
} else { {
int eno = errno; case AF_UNIX:
errno = 0; rc = unlink(config_bind);
if ((rc == -1) && (errno != ENOENT))
{
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
fprintf(stderr, skygw_log_write(LE, "Error: Failed to unlink Unix Socket %s: %d %s",
"\n* Failed to start listening MySQL due error %d, %s\n\n", config_bind, errno, strerror_r(errno, errbuf, sizeof (errbuf)));
eno, }
strerror_r(eno, errbuf, sizeof(errbuf)));
close(l_so); if (bind(l_so, (struct sockaddr *) &local_addr, sizeof (local_addr)) < 0)
{
char errbuf[STRERROR_BUFLEN];
skygw_log_write(LE,
"Error: Failed to bind to UNIX Domain socket '%s': %i, %s",
config_bind,
errno,
strerror_r(errno, errbuf, sizeof (errbuf)));
close(l_so);
return 0; return 0;
} }
// assign l_so to dcb
listen_dcb->fd = l_so;
// add listening socket to poll structure /* set permission for all users */
if (poll_add_dcb(listen_dcb) == -1) { if (chmod(config_bind, 0777) < 0)
fprintf(stderr, {
"\n* MaxScale encountered system limit while " char errbuf[STRERROR_BUFLEN];
"attempting to register on an epoll instance.\n\n"); skygw_log_write(LE,
return 0; "Error: Failed to change permissions on UNIX Domain socket '%s': %i, %s",
} config_bind,
errno,
strerror_r(errno, errbuf, sizeof (errbuf)));
}
break;
case AF_INET:
if (bind(l_so, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
{
char errbuf[STRERROR_BUFLEN];
skygw_log_write(LE,
"Error: Failed to bind on '%s': %i, %s",
config_bind,
errno,
strerror_r(errno, errbuf, sizeof (errbuf)));
close(l_so);
return 0;
}
break;
default:
skygw_log_write(LE, "Error: Socket Family %i not supported\n", current_addr->sa_family);
close(l_so);
return 0;
}
if (listen(l_so, 10 * SOMAXCONN) != 0)
{
char errbuf[STRERROR_BUFLEN];
skygw_log_write(LE,
"Failed to start listening on '%s': %d, %s",
config_bind,
errno,
strerror_r(errno, errbuf, sizeof (errbuf)));
close(l_so);
return 0;
}
LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, "Listening MySQL connections at %s", config_bind)));
// assign l_so to dcb
listen_dcb->fd = l_so;
// add listening socket to poll structure
if (poll_add_dcb(listen_dcb) != 0)
{
skygw_log_write(LE,
"MaxScale encountered system limit while "
"attempting to register on an epoll instance.");
return 0;
}
#if defined(FAKE_CODE) #if defined(FAKE_CODE)
conn_open[l_so] = true; conn_open[l_so] = true;
#endif /* FAKE_CODE */ #endif /* FAKE_CODE */
listen_dcb->func.accept = gw_MySQLAccept; listen_dcb->func.accept = gw_MySQLAccept;
return 1; return 1;
} }