diff --git a/server/modules/protocol/maxscaled.c b/server/modules/protocol/maxscaled.c index 0c5fa6614..9c37e93c8 100644 --- a/server/modules/protocol/maxscaled.c +++ b/server/modules/protocol/maxscaled.c @@ -38,11 +38,12 @@ #include #include -MODULE_INFO info = { - MODULE_API_PROTOCOL, - MODULE_GA, - GWPROTOCOL_VERSION, - "A maxscale protocol for the administration interface" +MODULE_INFO info = +{ + MODULE_API_PROTOCOL, + MODULE_GA, + GWPROTOCOL_VERSION, + "A maxscale protocol for the administration interface" }; /** @@ -51,8 +52,8 @@ MODULE_INFO info = { * * @verbatim * Revision History - * Date Who Description - * 13/06/2014 Mark Riddoch Initial implementation + * Date Who Description + * 13/06/2014 Mark Riddoch Initial implementation * 07/07/15 Martin Brampton Correct failure handling * * @endverbatim @@ -72,37 +73,36 @@ static int maxscaled_listen(DCB *dcb, char *config); /** * The "module object" for the maxscaled protocol module. */ -static GWPROTOCOL MyObject = { - maxscaled_read_event, /**< Read - EPOLLIN handler */ - maxscaled_write, /**< Write - data from gateway */ - maxscaled_write_event, /**< WriteReady - EPOLLOUT handler */ - maxscaled_error, /**< Error - EPOLLERR handler */ - maxscaled_hangup, /**< HangUp - EPOLLHUP handler */ - maxscaled_accept, /**< Accept */ - NULL, /**< Connect */ - maxscaled_close, /**< Close */ - maxscaled_listen, /**< Create a listener */ - NULL, /**< Authentication */ - NULL /**< Session */ - }; +static GWPROTOCOL MyObject = +{ + maxscaled_read_event, /**< Read - EPOLLIN handler */ + maxscaled_write, /**< Write - data from gateway */ + maxscaled_write_event, /**< WriteReady - EPOLLOUT handler */ + maxscaled_error, /**< Error - EPOLLERR handler */ + maxscaled_hangup, /**< HangUp - EPOLLHUP handler */ + maxscaled_accept, /**< Accept */ + NULL, /**< Connect */ + maxscaled_close, /**< Close */ + maxscaled_listen, /**< Create a listener */ + NULL, /**< Authentication */ + NULL /**< Session */ +}; /** * Implementation of the mandatory version entry point * * @return version string of the module */ -char * -version() +char* version() { - return version_str; + return version_str; } /** * The module initialisation routine, called when the module * is first loaded. */ -void -ModuleInit() +void ModuleInit() { MXS_INFO("Initialise MaxScaled Protocol module.");; } @@ -115,83 +115,85 @@ ModuleInit() * * @return The module object */ -GWPROTOCOL * -GetModuleObject() +GWPROTOCOL* GetModuleObject() { - return &MyObject; + return &MyObject; } /** * Read event for EPOLLIN on the maxscaled protocol module. * - * @param dcb The descriptor control block + * @param dcb The descriptor control block * @return */ -static int -maxscaled_read_event(DCB* dcb) +static int maxscaled_read_event(DCB* dcb) { -int n; -GWBUF *head = NULL; -SESSION *session = dcb->session; -MAXSCALED *maxscaled = (MAXSCALED *)dcb->protocol; -char *password; + int n; + GWBUF *head = NULL; + SESSION *session = dcb->session; + MAXSCALED *maxscaled = (MAXSCALED *)dcb->protocol; + char *password; - if ((n = dcb_read(dcb, &head, 0)) != -1) - { - - if (head) - { - if (GWBUF_LENGTH(head)) - { - switch (maxscaled->state) - { - case MAXSCALED_STATE_LOGIN: - maxscaled->username = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); - maxscaled->state = MAXSCALED_STATE_PASSWD; - dcb_printf(dcb, "PASSWORD"); - while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); - break; - case MAXSCALED_STATE_PASSWD: - password = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); - if (admin_verify(maxscaled->username, password)) - { - dcb_printf(dcb, "OK----"); - maxscaled->state = MAXSCALED_STATE_DATA; - } - else - { - dcb_printf(dcb, "FAILED"); - maxscaled->state = MAXSCALED_STATE_LOGIN; - } - while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); - free(password); - break; - case MAXSCALED_STATE_DATA: - SESSION_ROUTE_QUERY(session, head); - dcb_printf(dcb, "OK"); - break; - } - } - else - { - // Force the free of the buffer header - while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); - } - } - } - return n; + if ((n = dcb_read(dcb, &head, 0)) != -1) + { + if (head) + { + if (GWBUF_LENGTH(head)) + { + switch (maxscaled->state) + { + case MAXSCALED_STATE_LOGIN: + maxscaled->username = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); + maxscaled->state = MAXSCALED_STATE_PASSWD; + dcb_printf(dcb, "PASSWORD"); + while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); + break; + case MAXSCALED_STATE_PASSWD: + password = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); + if (admin_verify(maxscaled->username, password)) + { + dcb_printf(dcb, "OK----"); + maxscaled->state = MAXSCALED_STATE_DATA; + } + else + { + dcb_printf(dcb, "FAILED"); + maxscaled->state = MAXSCALED_STATE_LOGIN; + } + while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL) + { + ; + } + free(password); + break; + case MAXSCALED_STATE_DATA: + SESSION_ROUTE_QUERY(session, head); + dcb_printf(dcb, "OK"); + break; + } + } + else + { + // Force the free of the buffer header + while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL) + { + ; + } + } + } + } + return n; } /** * EPOLLOUT handler for the maxscaled protocol module. * - * @param dcb The descriptor control block + * @param dcb The descriptor control block * @return */ -static int -maxscaled_write_event(DCB *dcb) +static int maxscaled_write_event(DCB *dcb) { - return dcb_drain_writeq(dcb); + return dcb_drain_writeq(dcb); } /** @@ -200,184 +202,184 @@ maxscaled_write_event(DCB *dcb) * Writes the content of the buffer queue to the socket * observing the non-blocking principles of MaxScale. * - * @param dcb Descriptor Control Block for the socket - * @param queue Linked list of buffes to write + * @param dcb Descriptor Control Block for the socket + * @param queue Linked list of buffes to write */ -static int -maxscaled_write(DCB *dcb, GWBUF *queue) +static int maxscaled_write(DCB *dcb, GWBUF *queue) { - int rc; - rc = dcb_write(dcb, queue); - return rc; + int rc; + rc = dcb_write(dcb, queue); + return rc; } /** * Handler for the EPOLLERR event. * - * @param dcb The descriptor control block + * @param dcb The descriptor control block */ -static int -maxscaled_error(DCB *dcb) +static int maxscaled_error(DCB *dcb) { - return 0; + return 0; } /** * Handler for the EPOLLHUP event. * - * @param dcb The descriptor control block + * @param dcb The descriptor control block */ -static int -maxscaled_hangup(DCB *dcb) +static int maxscaled_hangup(DCB *dcb) { - dcb_close(dcb); - return 0; + dcb_close(dcb); + return 0; } /** * Handler for the EPOLLIN event when the DCB refers to the listening * socket for the protocol. * - * @param dcb The descriptor control block + * @param dcb The descriptor control block * @return The number of new connections created */ -static int -maxscaled_accept(DCB *dcb) +static int maxscaled_accept(DCB *dcb) { -int n_connect = 0; + int n_connect = 0; - while (1) - { - int so; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr); - DCB *client_dcb; - MAXSCALED *maxscaled_pr = NULL; + while (1) + { + int so; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(struct sockaddr); + DCB *client_dcb; + MAXSCALED *maxscaled_pr = NULL; - so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen); - - if (so == -1) - return n_connect; - else - { - atomic_add(&dcb->stats.n_accepts, 1); - client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); - if (client_dcb == NULL) - { - close(so); - return n_connect; - } - client_dcb->fd = so; - client_dcb->remote = strdup(inet_ntoa(addr.sin_addr)); - memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL)); - if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL) - { - client_dcb->protocol = NULL; - close(so); - dcb_close(client_dcb); - return n_connect; - } - maxscaled_pr->username = NULL; - spinlock_init(&maxscaled_pr->lock); - client_dcb->protocol = (void *)maxscaled_pr; + so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen); - client_dcb->session = - session_alloc(dcb->session->service, client_dcb); + if (so == -1) + { + return n_connect; + } + else + { + atomic_add(&dcb->stats.n_accepts, 1); + client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); + if (client_dcb == NULL) + { + close(so); + return n_connect; + } + client_dcb->fd = so; + client_dcb->remote = strdup(inet_ntoa(addr.sin_addr)); + memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL)); + if ((maxscaled_pr = (MAXSCALED *)malloc(sizeof(MAXSCALED))) == NULL) + { + client_dcb->protocol = NULL; + close(so); + dcb_close(client_dcb); + return n_connect; + } + maxscaled_pr->username = NULL; + spinlock_init(&maxscaled_pr->lock); + client_dcb->protocol = (void *)maxscaled_pr; - if (NULL == client_dcb->session || poll_add_dcb(client_dcb)) - { - dcb_close(dcb); - return n_connect; - } - n_connect++; - maxscaled_pr->state = MAXSCALED_STATE_LOGIN; - dcb_printf(client_dcb, "USER"); - } - } - return n_connect; + client_dcb->session = session_alloc(dcb->session->service, client_dcb); + + if (NULL == client_dcb->session || poll_add_dcb(client_dcb)) + { + dcb_close(dcb); + return n_connect; + } + n_connect++; + maxscaled_pr->state = MAXSCALED_STATE_LOGIN; + dcb_printf(client_dcb, "USER"); + } + } + return n_connect; } /** * The close handler for the descriptor. Called by the gateway to * explicitly close a connection. * - * @param dcb The descriptor control block + * @param dcb The descriptor control block */ -static int -maxscaled_close(DCB *dcb) +static int maxscaled_close(DCB *dcb) { -MAXSCALED *maxscaled = dcb->protocol; + MAXSCALED *maxscaled = dcb->protocol; - if (!maxscaled) - return 0; + if (!maxscaled) + { + return 0; + } - spinlock_acquire(&maxscaled->lock); - if (maxscaled->username) - { - free(maxscaled->username); - maxscaled->username = NULL; - } - spinlock_release(&maxscaled->lock); + spinlock_acquire(&maxscaled->lock); + if (maxscaled->username) + { + free(maxscaled->username); + maxscaled->username = NULL; + } + spinlock_release(&maxscaled->lock); - return 0; + return 0; } /** * Maxscale daemon listener entry point * - * @param listener The Listener DCB - * @param config Configuration (ip:port) + * @param listener The Listener DCB + * @param config Configuration (ip:port) */ -static int -maxscaled_listen(DCB *listener, char *config) +static int maxscaled_listen(DCB *listener, char *config) { -struct sockaddr_in addr; -int one = 1; -int rc; + struct sockaddr_in addr; + int one = 1; + int rc; - memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL)); + memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL)); - if (!parse_bindconfig(config, 6033, &addr)) - return 0; + if (!parse_bindconfig(config, 6033, &addr)) + { + return 0; + } + if ((listener->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + return 0; + } - if ((listener->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - return 0; - } + // socket options + if (setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))) + { + MXS_ERROR("Unable to set SO_REUSEADDR on maxscale listener."); + } + // set NONBLOCKING mode + setnonblocking(listener->fd); + // bind address and port + if (bind(listener->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + return 0; + } - // socket options - if (setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))) - { - MXS_ERROR("Unable to set SO_REUSEADDR on maxscale listener."); - } - // set NONBLOCKING mode - setnonblocking(listener->fd); - // bind address and port - if (bind(listener->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) - { - return 0; - } + rc = listen(listener->fd, SOMAXCONN); - rc = listen(listener->fd, SOMAXCONN); - - if (rc == 0) { - MXS_NOTICE("Listening maxscale connections at %s", config); - } else { - int eno = errno; - errno = 0; - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Failed to start listening for maxscale admin connections " - "due error %d, %s", - eno, strerror_r(eno, errbuf, sizeof(errbuf))); - return 0; - } + if (rc == 0) + { + MXS_NOTICE("Listening maxscale connections at %s", config); + } + else + { + int eno = errno; + errno = 0; + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Failed to start listening for maxscale admin connections " + "due error %d, %s", + eno, strerror_r(eno, errbuf, sizeof(errbuf))); + return 0; + } - - if (poll_add_dcb(listener) == -1) - { - return 0; - } - return 1; + if (poll_add_dcb(listener) == -1) + { + return 0; + } + return 1; }