diff --git a/server/core/config.c b/server/core/config.c index 334b560dc..4da5135e7 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -29,6 +29,7 @@ * 06/02/14 Massimiliano Pinto Added support for enable/disable root user in services * 14/02/14 Massimiliano Pinto Added enable_root_user in the service_params list * 11/03/14 Massimiliano Pinto Added Unix socket support + * 11/05/14 Massimiliano Pinto Added version_string support to service * * @endverbatim */ @@ -43,6 +44,7 @@ #include #include #include +#include extern int lm_enabled_logfiles_bitmask; @@ -56,6 +58,7 @@ static void check_config_objects(CONFIG_CONTEXT *context); static char *config_file = NULL; static GATEWAY_CONF gateway; +char *version_string = NULL; /** * Config item handler for the ini file reader @@ -116,6 +119,21 @@ config_load(char *file) CONFIG_CONTEXT config; int rval; + MYSQL *conn; + conn = mysql_init(NULL); + if (conn) { + if (mysql_real_connect(conn, NULL, NULL, NULL, NULL, 0, NULL, 0)) { + char *ptr; + version_string = (char *)mysql_get_server_info(conn); + ptr = strstr(version_string, "-embedded"); + if (ptr) { + *ptr = '\0'; + } + + } + mysql_close(conn); + } + global_defaults(); config.object = ""; @@ -146,6 +164,11 @@ int rval; if (!config_file) return 0; + + + if (gateway.version_string) + free(gateway.version_string); + global_defaults(); config.object = ""; @@ -202,6 +225,15 @@ int error_count = 0; config_get_value(obj->parameters, "passwd"); char *enable_root_user = config_get_value(obj->parameters, "enable_root_user"); + + char *version_string = config_get_value(obj->parameters, "version_string"); + + if (version_string) { + ((SERVICE *)(obj->element))->version_string = strdup(version_string); + } else { + if (gateway.version_string) + ((SERVICE *)(obj->element))->version_string = strdup(gateway.version_string); + } if (obj->element == NULL) /*< if module load failed */ { @@ -593,6 +625,10 @@ static void global_defaults() { gateway.n_threads = 1; + if (version_string != NULL) + gateway.version_string = strdup(version_string); + else + gateway.version_string = NULL; } /** @@ -635,6 +671,7 @@ SERVER *server; char *user; char *auth; char *enable_root_user; + char *version_string; enable_root_user = config_get_value(obj->parameters, "enable_root_user"); @@ -642,6 +679,15 @@ SERVER *server; "user"); auth = config_get_value(obj->parameters, "passwd"); + + version_string = config_get_value(obj->parameters, "version_string"); + + if (version_string) { + if (service->version_string) + free(service->version_string); + service->version_string = strdup(version_string); + } + if (user && auth) { service_update(service, router, user, @@ -874,6 +920,7 @@ static char *service_params[] = "user", "passwd", "enable_root_user", + "version_string", NULL }; diff --git a/server/core/service.c b/server/core/service.c index 08bc10b97..5b681c42b 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -28,6 +28,7 @@ * 06/02/14 Massimiliano Pinto Added: serviceEnableRootUser routine * 25/02/14 Massimiliano Pinto Added: service refresh limit feature * 28/02/14 Massimiliano Pinto users_alloc moved from service_alloc to serviceStartPort (generic hashable for services) + * 07/05/14 Massimiliano Pinto Added: version_string initialized to NULL * * @endverbatim */ @@ -91,6 +92,7 @@ SERVICE *service; } service->name = strdup(servname); service->routerModule = strdup(router); + service->version_string = NULL; memset(&service->stats, 0, sizeof(SERVICE_STATS)); service->ports = NULL; service->stats.started = time(0); @@ -175,7 +177,7 @@ GWPROTOCOL *funcs; if (port->listener->func.listen(port->listener, config_bind)) { port->listener->session = session_alloc(service, port->listener); - + if (port->listener->session != NULL) { port->listener->session->state = SESSION_STATE_LISTENER; listeners += 1; diff --git a/server/include/config.h b/server/include/config.h index 88620f015..03da9b029 100644 --- a/server/include/config.h +++ b/server/include/config.h @@ -24,8 +24,9 @@ * @verbatim * Revision History * - * Date Who Description - * 21/06/13 Mark Riddoch Initial implementation + * Date Who Description + * 21/06/13 Mark Riddoch Initial implementation + * 07/05/14 Massimiliano Pinto Added version_string to global configuration * * @endverbatim */ @@ -54,7 +55,8 @@ typedef struct config_context { * The gateway global configuration data */ typedef struct { - int n_threads; /**< Number of polling threads */ + int n_threads; /**< Number of polling threads */ + char *version_string; /**< The version string of embedded database library */ } GATEWAY_CONF; extern int config_load(char *); diff --git a/server/include/service.h b/server/include/service.h index d52a7eccf..0a8db9ea2 100644 --- a/server/include/service.h +++ b/server/include/service.h @@ -38,6 +38,7 @@ * 23/06/13 Mark Riddoch Added service user and users * 06/02/14 Massimiliano Pinto Added service flag for root user access * 25/02/14 Massimiliano Pinto Added service refresh limit feature + * 07/05/14 Massimiliano Pinto Added version_string field to service struct * * @endverbatim */ @@ -108,6 +109,7 @@ typedef struct service { *router; /**< The router we are using */ void *router_instance; /**< The router instance for this service */ + char *version_string; /** version string for this service listeners */ struct server *databases; /**< The set of servers in the backend */ SERVICE_USER credentials; /**< The cedentials of the service user */ SPINLOCK spin; /**< The service spinlock */ diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 5bd20f4f9..5e4c9bb21 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -33,6 +33,7 @@ * If current user is authenticated the new users' table will replace the old one * 28/02/2014 Massimiliano Pinto Added: client IPv4 in dcb->ipv4 and inet_ntop for string representation * 11/03/2014 Massimiliano Pinto Added: Unix socket support + * 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake * */ @@ -225,10 +226,21 @@ MySQLSendHandshake(DCB* dcb) uint8_t mysql_filler_ten[10]; uint8_t mysql_last_byte = 0x00; char server_scramble[GW_MYSQL_SCRAMBLE_SIZE + 1]=""; + char *version_string; + int len_version_string=0; MySQLProtocol *protocol = DCB_PROTOCOL(dcb, MySQLProtocol); GWBUF *buf; + /* get the version string from service property if available*/ + if (dcb->service->version_string != NULL) { + version_string = dcb->service->version_string; + len_version_string = strlen(version_string); + } else { + version_string = GW_MYSQL_VERSION; + len_version_string = strlen(GW_MYSQL_VERSION); + } + gw_generate_random_str(server_scramble, GW_MYSQL_SCRAMBLE_SIZE); // copy back to the caller @@ -245,7 +257,7 @@ MySQLSendHandshake(DCB* dcb) memcpy(mysql_plugin_data, server_scramble + 8, 12); - mysql_payload_size = sizeof(mysql_protocol_version) + (strlen(GW_MYSQL_VERSION) + 1) + sizeof(mysql_thread_id) + 8 + sizeof(mysql_filler) + sizeof(mysql_server_capabilities_one) + sizeof(mysql_server_language) + sizeof(mysql_server_status) + sizeof(mysql_server_capabilities_two) + sizeof(mysql_scramble_len) + sizeof(mysql_filler_ten) + 12 + sizeof(mysql_last_byte) + strlen("mysql_native_password") + sizeof(mysql_last_byte); + mysql_payload_size = sizeof(mysql_protocol_version) + (len_version_string + 1) + sizeof(mysql_thread_id) + 8 + sizeof(mysql_filler) + sizeof(mysql_server_capabilities_one) + sizeof(mysql_server_language) + sizeof(mysql_server_status) + sizeof(mysql_server_capabilities_two) + sizeof(mysql_scramble_len) + sizeof(mysql_filler_ten) + 12 + sizeof(mysql_last_byte) + strlen("mysql_native_password") + sizeof(mysql_last_byte); // allocate memory for packet header + payload if ((buf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size)) == NULL) @@ -271,8 +283,9 @@ MySQLSendHandshake(DCB* dcb) mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_protocol_version); // write server version plus 0 filler - strcpy((char *)mysql_handshake_payload, GW_MYSQL_VERSION); - mysql_handshake_payload = mysql_handshake_payload + strlen(GW_MYSQL_VERSION); + strcpy((char *)mysql_handshake_payload, version_string); + mysql_handshake_payload = mysql_handshake_payload + len_version_string; + *mysql_handshake_payload = 0x00; mysql_handshake_payload++;