├── AUTHORS ├── COPYING ├── COPYING.lfs ├── ChangeLog ├── Doxyfile ├── INSTALL ├── Makefile.in ├── NEWS ├── README.TESTS ├── README.md ├── README_ZH.md ├── THANKS ├── autogen.sh ├── bootstrap.sh ├── compile ├── config.guess ├── config.h.in ├── config.sub ├── configure ├── depcomp ├── deps ├── CMakeLists.txt ├── libevent.CMakeLists.txt ├── libevent.cmake ├── libevent.config.h.cmake ├── libevent.def ├── libevent.event-config.h.cmake ├── libevent.event.h.cmake └── libevent.evutil.h.cmake ├── doc ├── Makefile.am ├── Makefile.in ├── architecture-overview.dot ├── architecture.dot ├── architecture.txt ├── chapter │ ├── Makefile.am │ ├── Makefile.in │ ├── protocol.txt │ └── scripting.txt ├── chassis.txt ├── core.txt ├── lifecycle.msc ├── lua-classes.dot ├── plugins.txt ├── protocol.txt ├── scripting.txt └── tests.txt ├── doxygen-scripts ├── doxygen_version.sh ├── footer.html └── project_number_bzr.sh ├── example.cnf ├── examples ├── CMakeLists.txt ├── Makefile.am ├── Makefile.in ├── tutorial-basic.lua ├── tutorial-constants.lua ├── tutorial-inject.lua ├── tutorial-keepalive.lua ├── tutorial-monitor.lua ├── tutorial-packets.lua ├── tutorial-prep-stmts.lua ├── tutorial-query-time.lua ├── tutorial-resultset.lua ├── tutorial-rewrite.lua ├── tutorial-routing.lua ├── tutorial-scramble.lua ├── tutorial-states.lua ├── tutorial-tokenize.lua ├── tutorial-union.lua └── tutorial-warnings.lua ├── install-sh ├── lib ├── CMakeLists.txt ├── Makefile.am ├── Makefile.in ├── active-queries.lua ├── active-transactions.lua ├── admin-bak.lua ├── admin-sql.lua ├── admin.lua ├── analyze-query.lua ├── auditing.lua ├── chassis.c ├── chassis.def ├── commit-obfuscator.lua ├── commit-obfuscator.msc ├── crc32-lua.c ├── crc32.c ├── crc32.h ├── glib2.c ├── glib2.def ├── histogram.lua ├── lfs.c ├── lfs.def ├── load-multi.lua ├── lpeg.c ├── lpeg.def ├── mysql-password.c ├── mysql-proto.c ├── mysql.def ├── posix.c ├── posix.def ├── proxy │ ├── CMakeLists.txt │ ├── Makefile.am │ ├── Makefile.in │ ├── auth.lua │ ├── auto-config.lua │ ├── balance.lua │ ├── charset.lua │ ├── commands.lua │ ├── crc32.lua │ ├── filter.lua │ ├── log.lua │ ├── parser.lua │ ├── split.lua │ ├── test.lua │ ├── ticker.lua │ └── tokenizer.lua ├── ro-balance.lua ├── ro-pooling.lua ├── rw-splitting.lua ├── sql-tokenizer-gen.c ├── sql-tokenizer-keywords.h ├── sql-tokenizer-lua.c ├── sql-tokenizer-tokens.c ├── sql-tokenizer.h ├── sql-tokenizer.l ├── time-ticker-lua.c └── xtab.lua ├── ltmain.sh ├── m4 ├── Makefile.am ├── Makefile.in └── sed.m4 ├── missing ├── mysql-chassis.pc.in ├── mysql-proxy.pc.in ├── mysql-proxy.spec.in ├── plugins ├── CMakeLists.txt ├── Makefile.am ├── Makefile.in ├── admin │ ├── CMakeLists.txt │ ├── Makefile.am │ ├── Makefile.in │ └── admin-plugin.c ├── debug │ ├── CMakeLists.txt │ ├── Makefile.am │ ├── Makefile.in │ └── debug-plugin.c ├── proxy │ ├── CMakeLists.txt │ ├── Makefile.am │ ├── Makefile.in │ ├── proxy-plugin.c │ └── proxy-plugin.h └── replicant │ ├── CMakeLists.txt │ ├── Makefile.am │ ├── Makefile.in │ └── replicant-plugin.c ├── script ├── Makefile ├── create_table.sh ├── cron.sh ├── encrypt.c ├── instances ├── log.sh └── mysql-proxyd ├── src ├── CMakeLists.txt ├── Makefile.am ├── Makefile.in ├── chassis-event-thread.c ├── chassis-event-thread.h ├── chassis-exports.h ├── chassis-filemode.c ├── chassis-filemode.h ├── chassis-frontend.c ├── chassis-frontend.h ├── chassis-gtimeval.c ├── chassis-gtimeval.h ├── chassis-keyfile.c ├── chassis-keyfile.h ├── chassis-limits.c ├── chassis-limits.h ├── chassis-log.c ├── chassis-log.h ├── chassis-mainloop.c ├── chassis-mainloop.h ├── chassis-options.c ├── chassis-options.h ├── chassis-path.c ├── chassis-path.h ├── chassis-plugin.c ├── chassis-plugin.h ├── chassis-shutdown-hooks.c ├── chassis-shutdown-hooks.h ├── chassis-stats.c ├── chassis-stats.h ├── chassis-timings.c ├── chassis-timings.h ├── chassis-unix-daemon.c ├── chassis-unix-daemon.h ├── chassis-win32-service.c ├── chassis-win32-service.h ├── disable-dtrace.h ├── glib-ext-ref.c ├── glib-ext-ref.h ├── glib-ext.c ├── glib-ext.h ├── lua-env.c ├── lua-env.h ├── lua-load-factory.c ├── lua-load-factory.h ├── lua-registry-keys.h ├── lua-scope.c ├── lua-scope.h ├── my_rdtsc.c ├── my_rdtsc.h ├── my_timer_cycles.il ├── mysql-binlog-dump.c ├── mysql-myisam-dump.c ├── mysql-proxy-cli.c ├── network-address-lua.c ├── network-address-lua.h ├── network-address.c ├── network-address.h ├── network-backend-lua.c ├── network-backend-lua.h ├── network-backend.c ├── network-backend.h ├── network-conn-pool-lua.c ├── network-conn-pool-lua.h ├── network-conn-pool.c ├── network-conn-pool.h ├── network-debug.h ├── network-exports.h ├── network-injection-lua.c ├── network-injection-lua.h ├── network-injection.c ├── network-injection.h ├── network-mysqld-binlog.c ├── network-mysqld-binlog.h ├── network-mysqld-lua.c ├── network-mysqld-lua.h ├── network-mysqld-masterinfo.c ├── network-mysqld-masterinfo.h ├── network-mysqld-packet.c ├── network-mysqld-packet.h ├── network-mysqld-proto.c ├── network-mysqld-proto.h ├── network-mysqld.c ├── network-mysqld.h ├── network-queue.c ├── network-queue.h ├── network-socket-lua.c ├── network-socket-lua.h ├── network-socket.c ├── network-socket.h ├── network_mysqld_proto_binary.c ├── network_mysqld_proto_binary.h ├── network_mysqld_type.c ├── network_mysqld_type.h ├── proxy-dtrace-provider.d ├── string-len.h ├── sys-pedantic.h └── test-latency.c └── ylwrap /AUTHORS: -------------------------------------------------------------------------------- 1 | If you have questions about 2 | 3 | jan 4 | 5 | Zhu Chao(zhuchao@360.cn) 6 | Wang Chao(wangchao3@360.cn) 7 | Gui Yongzhe(guiyongzhe@360.cn) 8 | Feng Suofan(fengsuofan@360.cn) 9 | -------------------------------------------------------------------------------- /COPYING.lfs: -------------------------------------------------------------------------------- 1 | For the test-cases we include 2 | 3 | * LuaFileSystem 1.2 4 | 5 | which is covered by the following license 6 | 7 | --- 8 | Copyright © 2004-2005 The Kepler Project. 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of 11 | this software and associated documentation files (the "Software"), to deal in 12 | the Software without restriction, including without limitation the rights to 13 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 14 | of the Software, and to permit persons to whom the Software is furnished to do 15 | so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 26 | IN THE SOFTWARE. 27 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2.1 2 | *修正配置文件里的charset不生效的bug 3 | *修正update/delete分多张子表的bug 4 | *增加对MySQL Workbench, Navicat, SQLyog的支持 5 | *SQL日志里增加端口信息 6 | *改为每个工作线程一个消息队列 7 | *去除配置文件里的admin-lua-script项 8 | *配置文件里的instance项可不设置 9 | *主库可作为一台从库使用 10 | *屏蔽不带WHERE条件的UPDATE语句 11 | 12 | 2.0.5 13 | *连接失败时将unknown状态的DB置为down 14 | *将COM_SET_OPTION优先发往从库 15 | *从admin.lua里移除uuid和connected_clients 16 | 17 | 2.0.4 18 | *修正SET CHARACTER_[CLIENT|RESULTS|CONNECTION]的bug 19 | 20 | 2.0.3 21 | *支持客户端在连接时指定默认字符集 22 | 23 | 2.0.2 24 | *检测线程只检测状态为down的DB 25 | *处于事务状态的客户端退出时,Atlas销毁该客户端使用的连接 26 | 27 | 2.0.1 28 | *Java不能接受handshake包的随机串内包含负数,将随机串的每个字节的范围限定为[1,127] 29 | 30 | 2.0.0 31 | *实现了Atlas自行向DB建立连接,而不再依赖客户端的连接动作,并且把连接池由队列结构改为栈结构,带来的好处: 32 | **支持了长连接 33 | **不再需要min-idle-connections参数 34 | **连接池内的连接数可随着客户端并发量的上升而增长,且在并发量下降后自动销毁多余连接(依靠DB的wait_timeout) 35 | *SQL日志增加了开关,可以设为关闭(OFF)、打开(ON)、实时(REALTIME)三种,默认为OFF,REALTIME用于观察调试 36 | **OFF代表不记录SQL日志 37 | **ON代表记录SQL日志,由操作系统定期写入磁盘 38 | **REALTIME代表记录SQL日志,每记录一条都实时写入磁盘 39 | *启动脚本修改,在启动失败时可以报出错误信息 40 | *去除了配置文件的mode必须低于660的限制 41 | *检测线程不再将DB状态设为down,而是只在DB恢复后将其状态设为up,以此避免网络抖动引发的误将DB下线操作,减少无谓的lost connection 42 | *修正管理接口无法识别含有多个空格的语句的bug 43 | *去除全局保存的con结构队列,提升性能 44 | *不再判断is_insert_id,提升性能 45 | 46 | 0.7.0 - 47 | 48 | chassis 49 | * added a error-msg if trailing options without dashes are specified 50 | * added config-file support that maps cmdline options to configfile options 51 | * added support for SIGHUP to reopen logfiles 52 | * added win32-service support 53 | * added --basedir 54 | * added experimental --log-backtrace-on-crash 55 | * added DTrace probes 56 | * added a angel to keep the chassis alive 57 | * added --user option to change the system user the proxy runs as 58 | 59 | proxy-core 60 | * added buffered IO on unix 61 | * added lua-scope that is shared between the plugins 62 | * added a option to disable COM_CHANGE_USER on connection reuse 63 | * added handling of the 4.0 auth packets 64 | * added parser for master.info files 65 | * replaced assertions in protocol decoders by proper error-codes 66 | * fixed assertions when COM_TIME, COM_PROCESS_INFO or COM_DEBUG are received 67 | 68 | lua layer 69 | * added unit-testing for the lua scripts 70 | * fixed tutorial-inject.lua to start indexing at 1 (#32088) 71 | * expose chassis_log_* functions to lua 72 | * added the posix and lpeg module from luaforge 73 | * use the LPEG lua-module to parse statements 74 | * added memory profiling 75 | * added { resultset_is_needed = false } as default 76 | * moved proxy.backends.* to proxy.global.backends.* 77 | * added a lua-wrapper around some glib-2.0 functions 78 | * added a script cache 79 | * removed explicit call to lua_gc() to improve the speed 80 | 81 | Proxy Plugin 82 | * track rows and bytes of a resultset 83 | * fixed quoting of SQL commands like COMMIT and ROLLBACK 84 | * added test-cases for connection-pooling, fail-over, ... 85 | * refactored the SQL tokenizer into a lua module 86 | * fixed handling -- comments in the SQL tokenizer 87 | * fixed backend state cache 88 | 89 | Admin Plugin 90 | * replaced the hardcoded admin commands by a lua script interface 91 | * added authentication support 92 | 93 | Debug Plugin 94 | * return "number" as DOUBLE or INTs 95 | 96 | 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | We have build another interesting project [pika](https://github.com/Qihoo360/pika). Pika is a nosql compatible with redis protocol with huge storage space. You can have a try. 2 | 3 | ### 1.Brief introduction 4 | 5 | Atlas is a MySQL protocol-based database middleware project developed and maintained by infrastructure team of the Web platform Department in QIHU 360 SOFTWARE CO. LIMITED(NYSE:QIHU). It fixed lots of bugs and added lot of new functions on the basis of MySQL-Proxy 0.8.2. Currently the project has been widely applied in QIHU, many MySQL business has connected to the Atlas platform. The number of read and write requests forwarded by Atlas has reached billions. 6 | 7 | ### 2.Major functions 8 | 9 | 1.Read/Write Splitting. 10 | 11 | 2.Load balancing and failover handling. 12 | 13 | 3.IP filtering. 14 | 15 | 4.Data sharding 16 | 17 | 5.DBA can online or offline the backend database server smoothly. 18 | 19 | 6.Remove the failed database server automatically. 20 | 21 | 7.Config file reload without downtime. 22 | 23 | ### 3.The improvement of Atlas compared with Mysql-proxy 24 | 25 | 1.Rewrite all lua code with C, Lua is only used for management interface. 26 | 27 | 2.Rewrite the network model and the threading model. 28 | 29 | 3.Implement the connection pool. 30 | 31 | 4.Optimize the locking mechanism, performance improved immensely. 32 | 33 | ### 4.Detailed descriptions about Atlas 34 | 35 | [1.The installing of Atlas](https://github.com/Qihoo360/Atlas/wiki/Installing-Atlas) 36 | 37 | [2.The Architecture Of Atlas](https://github.com/Qihoo360/Atlas/wiki/The-Architecture-Of-Atlas) 38 | 39 | [3.The FAQs about the main features of Atlas](https://github.com/Qihoo360/Atlas/wiki/The-FAQs-about-the-main-features-of-Atlas) 40 | 41 | [4.The FAQs Of Running Atlas](https://github.com/Qihoo360/Atlas/wiki/The-FAQs-Of-Running-Atlas) 42 | 43 | ### 5.Requirement and feedback 44 | 45 | If You have new functional requirements about Atlas in the production environment, or find a bug in the process of using Atlas. Welcome to send a mail to g-atlas[at]360.cn, we will reply as soon as possible. Also you can contact us in [Google group](https://groups.google.com/forum/#!forum/atlas-proxy). Enthusiastic user has established a QQ group:326544838, the developers of Atlas have also been in the QQ group. 46 | 47 | ### 6.The origin of the name 48 | 49 | In Greek mythology, Atlas was the primordial Titan who held up the celestial spheres. He is also the titan of astronomy and navigation. 50 | 51 | ### 7.Other language version 52 | 53 | [简体中文](README_ZH.md) 54 | 55 | -------------------------------------------------------------------------------- /README_ZH.md: -------------------------------------------------------------------------------- 1 | 2 | 我们团队开发了另外一个有意思的项目 pika, pika 是一个兼容redis 协议的大容量的存储, 用来解决redis 内存不够的问题, 欢迎大家试试 3 | 4 | 由于团队精力有限, 目前Atlas 依据满足了公司大部分的需求, 因此很多Issue 我们很难再继续满足. 但是我们欢迎社区里面喜欢Atlas, 愿意给Atlas 做贡献的小伙伴可以一起来改善Atlas, 给Atlas 提交代码. 欢迎联系 g-infra@360.cn! 5 | ### 一、简介 6 | 7 | 8 | Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。同时,有超过50家公司在生产环境中部署了Atlas,超过800人已加入了我们的开发者交流群,并且这些数字还在不断增加。 9 | 10 | 主要功能: 11 | 12 | 1.读写分离 13 | 14 | 2.从库负载均衡 15 | 16 | 3.IP过滤 17 | 18 | 4.自动分表 19 | 20 | 5.DBA可平滑上下线DB 21 | 22 | 6.自动摘除宕机的DB 23 | 24 | ### 二、Atlas相对于官方MySQL-Proxy的优势 25 | 26 | 1.将主流程中所有Lua代码用C重写,Lua仅用于管理接口 27 | 28 | 2.重写网络模型、线程模型 29 | 30 | 3.实现了真正意义上的连接池 31 | 32 | 4.优化了锁机制,性能提高数十倍 33 | 34 | ### 三、Atlas详细说明 35 | 36 | [1.Atlas的安装](http://github.com/Qihoo360/Atlas/wiki/Atlas的安装) 37 | 38 | [2.Atlas的运行及常见问题](http://github.com/Qihoo360/Atlas/wiki/Atlas的运行及常见问题) 39 | 40 | [3.Atlas的分表功能简介](http://github.com/Qihoo360/Atlas/wiki/Atlas的分表功能简介) 41 | 42 | [4.Atlas部分配置参数及原理详解](http://github.com/Qihoo360/Atlas/wiki/Atlas部分配置参数及原理详解) 43 | 44 | [5.Atlas的架构](https://github.com/Qihoo360/Atlas/wiki/Atlas的架构) 45 | 46 | [6.Atlas的性能测试](https://github.com/Qihoo360/Atlas/wiki/Atlas的性能测试) 47 | 48 | [7.Atlas功能特点FAQ](https://github.com/Qihoo360/Atlas/wiki/Atlas功能特点FAQ) 49 | 50 | [8.Atlas Sharding](https://github.com/Qihoo360/Atlas/wiki/Atlas-Sharding) 51 | 52 | ### 四、Atlas的需求及Bug反馈方式 53 | 54 | 如果用户在实际的应用场景中对Atlas有新的功能需求,或者在使用Atlas的过程中发现了bug,欢迎用户发邮件至g-infra@360.cn,与我们取得联系,我们将及时回复。另外有热心网友建立了QQ群326544838,开发者也已经加入,方便讨论。 55 | 56 | ### 五、名字来源 57 | 58 | Atlas:希腊神话中双肩撑天的巨人,普罗米修斯的兄弟,最高大强壮的神之一,因反抗宙斯失败而被罚顶天。我们期望这个系统能够脚踏后端DB,为前端应用撑起一片天。 59 | 60 | ### 更多 61 | 62 | atlas、pika以及其他技术请关注:我们360私有云(HULK平台)平台微信公共号 63 | 2 64 | 65 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $%BEGINLICENSE%$ 3 | # $%ENDLICENSE%$ 4 | 5 | # Run this to generate all the initial makefiles, etc. 6 | 7 | # LIBTOOLIZE=${LIBTOOLIZE:-libtoolize} 8 | LIBTOOLIZE_FLAGS="--copy --force" 9 | # ACLOCAL=${ACLOCAL:-aclocal} 10 | # AUTOHEADER=${AUTOHEADER:-autoheader} 11 | # AUTOMAKE=${AUTOMAKE:-automake} 12 | AUTOMAKE_FLAGS="--add-missing --copy" 13 | # AUTOCONF=${AUTOCONF:-autoconf} 14 | 15 | ARGV0=$0 16 | ARGS="$@" 17 | 18 | 19 | run() { 20 | echo "$ARGV0: running \`$@' $ARGS" 21 | $@ $ARGS 22 | } 23 | 24 | ## jump out if one of the programs returns 'false' 25 | set -e 26 | 27 | ## on macosx glibtoolize, others have libtool 28 | if test x$LIBTOOLIZE = x; then 29 | if test \! "x`which glibtoolize 2> /dev/null | grep -v '^no'`" = x; then 30 | LIBTOOLIZE=glibtoolize 31 | elif test \! "x`which libtoolize 2> /dev/null | grep -v '^no'`" = x; then 32 | LIBTOOLIZE=libtoolize 33 | else 34 | echo "libtoolize wasn't found, try setting LIBTOOLIZE={path-to-libtool}."; exit 0 35 | fi 36 | fi 37 | 38 | if test x$ACLOCAL = x; then 39 | if test \! "x`which aclocal 2> /dev/null | grep -v '^no'`" = x; then 40 | ACLOCAL=aclocal 41 | else 42 | echo "aclocal 1.10+ wasn't found, try setting ACLOCAL={path-to-aclocal}."; exit 0 43 | fi 44 | fi 45 | 46 | if test x$AUTOMAKE = x; then 47 | if test \! "x`which automake 2> /dev/null | grep -v '^no'`" = x; then 48 | AUTOMAKE=automake 49 | else 50 | echo "automake 1.10+ wasn't found, try setting AUTOMAKE={path-to-automake}."; exit 0 51 | fi 52 | fi 53 | 54 | 55 | if test x$AUTOCONF = x; then 56 | if test \! "x`which autoconf 2> /dev/null | grep -v '^no'`" = x; then 57 | AUTOCONF=autoconf 58 | else 59 | echo "autoconf 2.62+ wasn't found, try setting AUTOCONF={path-to-autoconf}."; exit 0 60 | fi 61 | fi 62 | 63 | if test x$AUTOHEADER = x; then 64 | if test \! "x`which autoheader 2> /dev/null | grep -v '^no'`" = x; then 65 | AUTOHEADER=autoheader 66 | else 67 | echo "autoheader 2.62+ (autoheader) wasn't found, try setting AUTOHEADER={path-to-autoheader}."; exit 0 68 | fi 69 | fi 70 | 71 | 72 | run $LIBTOOLIZE $LIBTOOLIZE_FLAGS 73 | run $ACLOCAL $ACLOCAL_FLAGS -I m4 74 | run $AUTOHEADER 75 | run $AUTOMAKE $AUTOMAKE_FLAGS 76 | run $AUTOCONF 77 | test "$ARGS" = "" && echo "Now type './configure --enable-maintainer-mode ...' and 'make' to compile." 78 | 79 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | base=$(cd "$(dirname "$0")"; pwd) 3 | cd $base 4 | export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH 5 | PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --with-mysql=/usr --prefix=/usr/local/mysql-proxy CFLAGS="-DHAVE_LUA_H -O2" LDFLAGS="-lm -ldl -lcrypto -ljemalloc" LUA_CFLAGS="-I/usr/local/include/" LUA_LIBS="-L/usr/local/lib -llua" 6 | -------------------------------------------------------------------------------- /deps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # INCLUDE(deps/libevent.cmake) 2 | -------------------------------------------------------------------------------- /deps/libevent.cmake: -------------------------------------------------------------------------------- 1 | IF(WIN32) 2 | SET(LIBEVENT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/deps/libevent-1.4.11-stable") 3 | IF(EXISTS ${LIBEVENT_SOURCE_DIR}) 4 | ## write CMake file for libevent 5 | 6 | CONFIGURE_FILE(deps/libevent.config.h.cmake ${LIBEVENT_SOURCE_DIR}/config.h.cmake COPYONLY) 7 | CONFIGURE_FILE(deps/libevent.event-config.h.cmake ${LIBEVENT_SOURCE_DIR}/event-config.h.cmake COPYONLY) 8 | CONFIGURE_FILE(deps/libevent.CMakeLists.txt ${LIBEVENT_SOURCE_DIR}/CMakeLists.txt COPYONLY) 9 | CONFIGURE_FILE(deps/libevent.def ${LIBEVENT_SOURCE_DIR}/libevent.def COPYONLY) 10 | ## CONFIGURE_FILE(deps/libevent.event.h.cmake ${LIBEVENT_SOURCE_DIR}/event.h COPYONLY) 11 | ## CONFIGURE_FILE(deps/libevent.evutil.h.cmake ${LIBEVENT_SOURCE_DIR}/evutil.h COPYONLY) 12 | 13 | ADD_SUBDIRECTORY(${LIBEVENT_SOURCE_DIR} build-libevent) 14 | 15 | SET(EVENT_INCLUDE_DIRS ${LIBEVENT_SOURCE_DIR} CACHE INTERNAL "") 16 | IF(EXISTS ${CMAKE_BINARY_DIR}/build-libevent/${CMAKE_BUILD_TYPE}/) 17 | SET(EVENT_LIBRARY_DIRS ${CMAKE_BINARY_DIR}/build-libevent/${CMAKE_BUILD_TYPE} CACHE INTERNAL "") 18 | ELSE(EXISTS ${CMAKE_BINARY_DIR}/build-libevent/${CMAKE_BUILD_TYPE}/) 19 | SET(EVENT_LIBRARY_DIRS ${CMAKE_BINARY_DIR}/build-libevent CACHE INTERNAL "") 20 | ENDIF(EXISTS ${CMAKE_BINARY_DIR}/build-libevent/${CMAKE_BUILD_TYPE}/) 21 | SET(EVENT_LIBRARIES event CACHE INTERNAL "") 22 | ELSE(EXISTS ${LIBEVENT_SOURCE_DIR}) 23 | MESSAGE(FATAL_ERROR "Could not find dependency libevent-1.4.11-stable in ${LIBEVENT_SOURCE_DIR}") 24 | ENDIF(EXISTS ${LIBEVENT_SOURCE_DIR}) 25 | ENDIF(WIN32) 26 | -------------------------------------------------------------------------------- /deps/libevent.config.h.cmake: -------------------------------------------------------------------------------- 1 | #cmakedefine HAVE_STDINT_H 2 | #cmakedefine HAVE_SYS_TIME_H 3 | #cmakedefine HAVE_SYS_TREE_H 4 | #cmakedefine HAVE_FCNTL_H 5 | #cmakedefine HAVE_STDARG_H 6 | #cmakedefine HAVE_INTTYPES_H 7 | #cmakedefine HAVE_STDLIB_H 8 | #cmakedefine HAVE_POLL_H 9 | #cmakedefine HAVE_SIGNAL_H 10 | #cmakedefine HAVE_UNISTD_H 11 | #cmakedefine HAVE_SYS_DEVPOLL_H 12 | #cmakedefine HAVE_PORT_H 13 | #cmakedefine HAVE_KQUEUE_H 14 | 15 | #cmakedefine HAVE_POLL 16 | #cmakedefine HAVE_SELECT 17 | #cmakedefine HAVE_GETTIMEOFDAY 18 | #cmakedefine HAVE_VASPRINTF 19 | #cmakedefine HAVE_FCNTL 20 | #cmakedefine HAVE_CLOCK_GETTIME 21 | #cmakedefine HAVE_STRTOK_R 22 | #cmakedefine HAVE_STRSEP 23 | #cmakedefine HAVE_GETADDRINFO 24 | #cmakedefine HAVE_GETNAMEINFO 25 | #cmakedefine HAVE_STRLCPY 26 | #cmakedefine HAVE_INET_NTOP 27 | #cmakedefine HAVE_SIGTIMEDWAIT 28 | #cmakedefine HAVE_EPOLL 29 | #cmakedefine HAVE_KQUEUE 30 | #cmakedefine HAVE_TIMERADD 31 | #cmakedefine HAVE_TIMERSUB 32 | #cmakedefine HAVE_TIMERISSET 33 | #cmakedefine HAVE_TIMERCLEAR 34 | 35 | #define VERSION "libevent-1.4.11-stable" 36 | -------------------------------------------------------------------------------- /deps/libevent.def: -------------------------------------------------------------------------------- 1 | LIBRARY event.dll 2 | EXPORTS 3 | event_base_new 4 | event_init 5 | event_reinit 6 | event_dispatch 7 | event_base_dispatch 8 | event_base_get_method 9 | event_base_free 10 | event_set_log_callback 11 | event_base_set 12 | event_loop 13 | event_base_loop 14 | event_loopexit 15 | event_base_loopexit 16 | event_loopbreak 17 | event_base_loopbreak 18 | event_set 19 | event_once 20 | event_base_once 21 | event_add 22 | event_del 23 | event_active 24 | event_pending 25 | event_get_version 26 | event_get_method 27 | bufferevent_new 28 | bufferevent_base_set 29 | bufferevent_priority_set 30 | bufferevent_free 31 | bufferevent_setcb 32 | bufferevent_setfd 33 | bufferevent_write 34 | bufferevent_write_buffer 35 | bufferevent_read 36 | bufferevent_enable 37 | bufferevent_disable 38 | bufferevent_settimeout 39 | bufferevent_setwatermark 40 | evbuffer_new 41 | evbuffer_free 42 | evbuffer_expand 43 | evbuffer_add 44 | evbuffer_remove 45 | evbuffer_readline 46 | evbuffer_add_buffer 47 | evbuffer_add_printf 48 | evbuffer_add_vprintf 49 | evbuffer_drain 50 | evbuffer_write 51 | evbuffer_read 52 | evbuffer_find 53 | evbuffer_setcb 54 | evtag_init 55 | evtag_marshal 56 | encode_int 57 | evtag_marshal_int 58 | evtag_marshal_string 59 | evtag_marshal_timeval 60 | evtag_unmarshal 61 | evtag_peek 62 | evtag_peek_length 63 | evtag_payload_length 64 | evtag_consume 65 | evtag_unmarshal_int 66 | evtag_unmarshal_fixed 67 | evtag_unmarshal_string 68 | evtag_unmarshal_timeval 69 | evutil_socketpair 70 | evutil_make_socket_nonblocking 71 | -------------------------------------------------------------------------------- /deps/libevent.event-config.h.cmake: -------------------------------------------------------------------------------- 1 | #cmakedefine _EVENT_HAVE_STDINT_H 2 | #cmakedefine _EVENT_HAVE_SYS_TIME_H 3 | #cmakedefine _EVENT_HAVE_SYS_TREE_H 4 | #cmakedefine _EVENT_HAVE_FCNTL_H 5 | #cmakedefine _EVENT_HAVE_STDARG_H 6 | #cmakedefine _EVENT_HAVE_INTTYPES_H 7 | #cmakedefine _EVENT_HAVE_STDLIB_H 8 | #cmakedefine _EVENT_HAVE_POLL_H 9 | #cmakedefine _EVENT_HAVE_SIGNAL_H 10 | #cmakedefine _EVENT_HAVE_UNISTD_H 11 | #cmakedefine _EVENT_HAVE_SYS_DEVPOLL_H 12 | #cmakedefine _EVENT_HAVE_PORT_H 13 | #cmakedefine _EVENT_HAVE_KQUEUE_H 14 | 15 | #cmakedefine _EVENT_HAVE_POLL 16 | #cmakedefine _EVENT_HAVE_SELECT 17 | #cmakedefine _EVENT_HAVE_GETTIMEOFDAY 18 | #cmakedefine _EVENT_HAVE_VASPRINTF 19 | #cmakedefine _EVENT_HAVE_FCNTL 20 | #cmakedefine _EVENT_HAVE_CLOCK_GETTIME 21 | #cmakedefine _EVENT_HAVE_STRTOK_R 22 | #cmakedefine _EVENT_HAVE_STRSEP 23 | #cmakedefine _EVENT_HAVE_GETADDRINFO 24 | #cmakedefine _EVENT_HAVE_GETNAMEINFO 25 | #cmakedefine _EVENT_HAVE_STRLCPY 26 | #cmakedefine _EVENT_HAVE_INET_NTOP 27 | #cmakedefine _EVENT_HAVE_SIGTIMEDWAIT 28 | #cmakedefine _EVENT_HAVE_EPOLL 29 | #cmakedefine _EVENT_HAVE_KQUEUE 30 | #cmakedefine _EVENT_HAVE_TIMERADD 31 | #cmakedefine _EVENT_HAVE_TIMERSUB 32 | #cmakedefine _EVENT_HAVE_TIMERISSET 33 | #cmakedefine _EVENT_HAVE_TIMERCLEAR 34 | 35 | #define _EVENT_VERSION "libevent-1.4.11-stable" 36 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=chapter 2 | 3 | EXTRA_DIST = \ 4 | lua-classes.dot \ 5 | architecture.dot \ 6 | architecture-overview.dot \ 7 | architecture.txt \ 8 | core.txt \ 9 | chassis.txt \ 10 | plugins.txt \ 11 | protocol.txt \ 12 | tests.txt \ 13 | scripting.txt \ 14 | lifecycle.msc 15 | 16 | clean-local: 17 | rm -f *.html 18 | 19 | html-local: book.html protocol.html scripting.html 20 | 21 | ## we use http://docutils.sourceforge.net/rst.html to generate the docs 22 | book.html: book.txt chapter/scripting.txt chapter/protocol.txt 23 | ${RST2HTML} $< $@ 24 | 25 | protocol.html: protocol.txt chapter/protocol.txt 26 | ${RST2HTML} $< $@ 27 | 28 | scripting.html: scripting.txt chapter/scripting.txt 29 | ${RST2HTML} $< $@ 30 | 31 | -------------------------------------------------------------------------------- /doc/architecture-overview.dot: -------------------------------------------------------------------------------- 1 | /* 2 | the building blocks of the proxy 3 | 4 | You may use "dot" from graphviz to generate human consumable output 5 | like PNG or PDF: 6 | 7 | $ dot -T pdf -o architecture.pdf architecture.dot 8 | $ dot -T png -o architecture.png architecture.dot 9 | 10 | or you generate a image-map 11 | 12 | $ dot -T cmapx -o architecture.map -Tpng -o architecture.png architecture.dot && \ 13 | echo '' > architecture.html && \ 14 | cat architecture.map >> architecture.html 15 | */ 16 | digraph G { 17 | node [ 18 | shape = "plaintext" 19 | fontname = "Courier" 20 | fontsize = 10 21 | ] 22 | 23 | rank = "same"; 24 | rankdir = "LR"; 25 | subgraph clients { 26 | Clients1 [ 27 | label = < 28 | 29 | 30 | 33 | 34 |
31 | Client 32 |
35 | 36 | 37 | 38 |
app
39 |
40 | > 41 | ]; 42 | 43 | Clients2 [ 44 | label = < 45 | 46 | 47 | 50 | 51 |
48 | Client 49 |
52 | 53 | 54 | 55 |
app
56 |
57 | > 58 | ]; 59 | } 60 | 61 | subgraph backends { 62 | Backend1 [ 63 | label = < 64 | 65 | 66 | 69 | 70 |
67 | MySQL Server 68 |
71 | 72 | 73 | 74 |
10.0.0.1:3306
75 |
76 | > 77 | 78 | ]; 79 | 80 | Backend2 [ 81 | label = < 82 | 83 | 84 | 87 | 88 |
85 | MySQL Server 86 |
89 | 90 | 91 | 92 |
10.0.0.2:3306
93 |
94 | > 95 | 96 | ]; 97 | 98 | } 99 | 100 | Blocks [ 101 | label = < 102 | 103 | 104 | 107 | 108 |
105 | MySQL Proxy 106 |
109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
script
plugin
network core
119 |
120 | > 121 | ] 122 | 123 | 124 | Clients1:app:e -> Blocks:w; 125 | Clients2:app:e -> Blocks:w; 126 | Blocks:e -> Backend1:port:w; 127 | Blocks:e -> Backend2:port:w; 128 | } 129 | -------------------------------------------------------------------------------- /doc/architecture.txt: -------------------------------------------------------------------------------- 1 | /** 2 | @mainpage 3 | 4 | The MySQL Proxy is a simple program which sits between a mysql client and a mysql server and 5 | can inspect, transform and act on the data sent through it. 6 | 7 | You can use it for: 8 | @li load balancing 9 | @li fail over 10 | @li query tracking 11 | @li query analysis 12 | @li ... and much more 13 | 14 | Internally the MySQL Proxy is a stack of: 15 | 16 | @dotfile architecture-overview.dot 17 | 18 | It is based on a @subpage page-core that exposes the phases of the 19 | @subpage protocol to a @ref page-plugins. 20 | 21 | @dot 22 | digraph { 23 | connect -> auth; 24 | auth -> command; 25 | command -> disconnect; 26 | command -> command; 27 | connect -> disconnect; 28 | auth -> disconnect; 29 | } 30 | 31 | @enddot 32 | 33 | Each of the phases of the life-cycle lead to several more protocol-states. For example the auth phase is made up of at least 3 packets: 34 | 35 | @msc 36 | Client, Proxy, Server; 37 | 38 | Client -> Proxy [ label = "accept()" ]; 39 | Proxy -> Proxy [ label = "script: connect_server()" ]; 40 | Proxy -> Server [ label = "connect()" ]; 41 | ...; 42 | Server -> Proxy [ label = "recv(auth-challenge)" ]; 43 | Proxy -> Proxy [ label = "script: read_handshake()" ]; 44 | Proxy -> Client [ label = "send(auth-challenge)" ]; 45 | Client -> Proxy [ label = "recv(auth-response)" ]; 46 | Proxy -> Proxy [ label = "script: read_auth()" ]; 47 | Server -> Proxy [ label = "send(auth-response)" ]; 48 | Server -> Proxy [ label = "recv(auth-result)" ]; 49 | Proxy -> Proxy [ label = "script: read_auth_result()" ]; 50 | Proxy -> Client [ label = "send(auth-result)" ]; 51 | ...; 52 | 53 | @endmsc 54 | 55 | While the @ref page-core is scalable to a larger number of connections, the plugin/scripting 56 | layer hides the complexity from the end-users and simplifies the customization. 57 | 58 | @section section-stack-of-libs Chassis, libraries and Plugins 59 | 60 | It is built as a stack of libraries: 61 | 62 | The @subpage page-chassis provides the common functions that all commandline and daemon applications 63 | need: 64 | @li commandline and configfiles 65 | @li logging 66 | @li daemon/service support 67 | @li plugin loading 68 | 69 | The MySQL Procotol libraries which can encode and decode: 70 | @li client protocol 71 | @li binlog protocol 72 | @li myisam files 73 | @li frm files 74 | @li masterinfo files 75 | 76 | The @ref page-core and the @subpage page-plugins. 77 | 78 | @dotfile architecture.dot 79 | 80 | */ 81 | -------------------------------------------------------------------------------- /doc/chapter/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST=\ 2 | protocol.txt \ 3 | scripting.txt 4 | 5 | -------------------------------------------------------------------------------- /doc/core.txt: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | @page page-core Network Core 4 | 5 | The Network core is built around the socket handling and brings a client and server connection 6 | together. 7 | 8 | @see network_socket 9 | @see network_mysqld_con 10 | 11 | @section section-lifecycle Connection Life Cycle 12 | 13 | Connections can be in one of several states which are basicly resembling the 4 basic phases 14 | of the @ref protocol : 15 | 16 | @li connect 17 | @li authentification 18 | @li query 19 | @li disconnect 20 | 21 | The plugins can change the default behaviour of the network core and impliment one of three 22 | basic plugins: 23 | 24 | @li @ref page-plugin-admin implements only the listening side 25 | @li client plugins implement only the connection side 26 | @li @ref page-plugin-proxy implements both sides 27 | 28 | @subsection section-scripting Scripting 29 | 30 | Most plugins implement a set of those callbacks and expose them to a scripting layer. 31 | 32 | For now the scriping is provided by Lua, a simple, fast and easy to embed scripting language. 33 | We expose most of the internals into the scripting layer and provide modules to operate 34 | on the data that we pass into the scripting layer 35 | 36 | @section section-network-core-layer Network Core Layer 37 | 38 | The MySQL Proxy network engine is meant to handle several thousands connections at the same time. We 39 | want to use it for load-balancing and fail-over which means we have to handle the connections for 40 | a larger group of MySQL backend servers nicely. We aim for 5k to 10k connections. 41 | Up to MySQL Proxy 0.7 we use a pure event-driven, non-blocking networking approach is described in 42 | http://kegel.com/c10k.html#nb using libevent 1.4.x. 43 | A event-driven design has a very small foot-print for idling connections: we just store the 44 | connection state and let it wait for a event. 45 | 46 | @section section-threaded-scripting Threaded Scripting 47 | 48 | Usually the scripts are small and only make simple decisions leaving most of the work to the network layer. 49 | In 0.9 we will make the scripting layer multi-threaded allow several scripting threads at the same time, 50 | working from a small pool threads. 51 | 52 | That will allow the scripting layer to call blocking or slow functions without infecting the execution of 53 | other connections. 54 | 55 | Lifting the global plugin mutex will mean we have to handle access to global structure differently. Most 56 | of the access is happening on connection-level (the way we do the event-threading) and only access to 57 | global structures like "proxy.global.*" has to synchronized. For that we will look into using Lua lanes 58 | to send data around between independent Lua-states. 59 | 60 | 61 | 62 | 63 | */ 64 | -------------------------------------------------------------------------------- /doc/lifecycle.msc: -------------------------------------------------------------------------------- 1 | # 2 | # mscgen -T png -o lifecycle.png < lifecycle.msc 3 | 4 | 5 | 6 | msc { 7 | Client, Core, Plugin, Server; 8 | 9 | # Core box Plugin [ label = "MySQL Proxy" ]; 10 | 11 | --- [ label = "connect" ]; 12 | Client -> Core [ label = "connect()" ]; 13 | Core => Plugin [ label = "connect_server()" ]; 14 | Core << Plugin [ label = "NO_DECISION" ]; 15 | Core -> Server [ label = "connect()" ]; 16 | 17 | --- [ label = "auth challenge" ]; 18 | Server -> Core [ label = "read(auth challenge packet)" ]; 19 | Core => Plugin [ label = "read_auth_handshake()" ]; 20 | Core << Plugin [ label = "NO_DECISION" ]; 21 | Core -> Client [ label = "write(auth challenge packet)" ]; 22 | --- [ label = "auth response" ]; 23 | Client -> Core [ label = "read(auth response packet)" ]; 24 | Core => Plugin [ label = "read_auth()" ]; 25 | Core << Plugin [ label = "NO_DECISION" ]; 26 | Core -> Server [ label = "write(auth response packet)" ]; 27 | --- [ label = "auth status" ]; 28 | Server -> Core [ label = "read(auth response packet)" ]; 29 | Core => Plugin [ label = "read_auth_result()" ]; 30 | Core << Plugin [ label = "NO_DECISION" ]; 31 | Core -> Client [ label = "write(auth response packet)" ]; 32 | --- [ label = "query" ]; 33 | Client -> Core [ label = "read(command packet)" ]; 34 | Core => Plugin [ label = "read_query()" ]; 35 | Core << Plugin [ label = "NO_DECISION" ]; 36 | Core -> Server [ label = "write(command packet)" ]; 37 | --- [ label = "query response" ]; 38 | Server -> Core [ label = "read(command response packet)" ]; 39 | Core => Plugin [ label = "read_query_result()" ]; 40 | Core << Plugin [ label = "NO_DECISION" ]; 41 | Core -> Client [ label = "write(command response packet)" ]; 42 | 43 | --- [ label = "disconnect" ]; 44 | Client -> Core [ label = "close()" ]; 45 | Core => Plugin [ label = "disconnect_client()" ]; 46 | Core << Plugin [ label = "ignored" ]; 47 | Core -> Server [ label = "close()" ]; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /doc/plugins.txt: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | @page page-plugins Plugin and Scripting Layer 4 | 5 | What is usually being referred to as MySQL Proxy is in fact the @link page-plugin-proxy Proxy plugin@endlink. 6 | 7 | While the @ref page-chassis and @ref page-core make up an important part, it is really the plugins that make MySQL Proxy so flexible. 8 | 9 | One can describe the currently available plugins as connection lifecycle interceptors which can register callbacks for 10 | all states in the @ref protocol. 11 | 12 | Currently available plugins in the main distribution include: 13 | - @subpage page-plugin-proxy 14 | - @subpage page-plugin-admin 15 | - Replicator plugin 16 | - Debug plugin 17 | - CLI (command line) plugin 18 | 19 | @note The latter three are not documented in-depth, mainly because they are Proof Of Concept implementations that are not targeted 20 | for the MySQL Proxy 1.0 GA release. 21 | 22 | */ 23 | -------------------------------------------------------------------------------- /doc/protocol.txt: -------------------------------------------------------------------------------- 1 | ============== 2 | MySQL Protocol 3 | ============== 4 | 5 | .. contents:: 6 | 7 | .. include:: chapter/protocol.txt 8 | 9 | -------------------------------------------------------------------------------- /doc/scripting.txt: -------------------------------------------------------------------------------- 1 | ========================== 2 | Scripting the proxy plugin 3 | ========================== 4 | 5 | .. contents:: 6 | 7 | .. include:: chapter/scripting.txt 8 | 9 | -------------------------------------------------------------------------------- /doxygen-scripts/doxygen_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $%BEGINLICENSE%$ 3 | # $%ENDLICENSE%$ 4 | 5 | bzr log --limit 1 --line $1 | sed -n 's/^\([0-9]*\):.*$/\1/p' 6 | -------------------------------------------------------------------------------- /doxygen-scripts/footer.html: -------------------------------------------------------------------------------- 1 |
2 | Generated on $datetime for $projectname version $projectnumber.
3 | 4 | 5 | -------------------------------------------------------------------------------- /doxygen-scripts/project_number_bzr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $%BEGINLICENSE%$ 3 | # $%ENDLICENSE%$ 4 | 5 | VERSION_INFO=`bzr version-info --custom --template="{branch_nick} Revision {revno} from {date}"` 6 | echo "\"$1 - $VERSION_INFO\"" 7 | -------------------------------------------------------------------------------- /example.cnf: -------------------------------------------------------------------------------- 1 | [mysql-proxy] 2 | admin-username=admin 3 | admin-password=admin_password 4 | admin-lua-script=/usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua 5 | log-level=message 6 | log-path=./log 7 | plugin-dir=./lib 8 | daemon=false 9 | keepalive=false 10 | event-threads=2 11 | instance=3470 12 | proxy-address=0.0.0.0:13470 13 | admin-address=0.0.0.0:23470 14 | proxy-backend-addresses=192.168.1.1:3306 15 | proxy-read-only-backend-addresses=192.168.1.2:3306 16 | client-ips=127.0.0.1,192.168.1,192.168.2.35 17 | lvs-ips=192.168.0.1 18 | pwds=user_name:user_password 19 | charset=utf8 20 | sql-log=ON 21 | max_conn_for_a_backend=0 22 | wait-timeout=60 23 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## automake uses 2 | ## 3 | ## docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} 4 | ## 5 | ## so do we 6 | INSTALL(FILES 7 | tutorial-basic.lua 8 | tutorial-constants.lua 9 | tutorial-inject.lua 10 | tutorial-keepalive.lua 11 | tutorial-monitor.lua 12 | tutorial-packets.lua 13 | tutorial-query-time.lua 14 | tutorial-resultset.lua 15 | tutorial-rewrite.lua 16 | tutorial-routing.lua 17 | tutorial-states.lua 18 | tutorial-tokenize.lua 19 | tutorial-union.lua 20 | tutorial-warnings.lua 21 | 22 | DESTINATION share/doc/mysql-proxy/ 23 | ) 24 | -------------------------------------------------------------------------------- /examples/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST= 2 | 3 | example_scripts = \ 4 | tutorial-basic.lua \ 5 | tutorial-constants.lua \ 6 | tutorial-inject.lua \ 7 | tutorial-keepalive.lua \ 8 | tutorial-monitor.lua \ 9 | tutorial-packets.lua \ 10 | tutorial-query-time.lua \ 11 | tutorial-prep-stmts.lua \ 12 | tutorial-resultset.lua \ 13 | tutorial-rewrite.lua \ 14 | tutorial-routing.lua \ 15 | tutorial-scramble.lua \ 16 | tutorial-states.lua \ 17 | tutorial-tokenize.lua \ 18 | tutorial-union.lua \ 19 | tutorial-warnings.lua 20 | 21 | if USE_WRAPPER_SCRIPT 22 | dist_doc_DATA = ${example_scripts} 23 | else 24 | EXTRA_DIST += ${example_scripts} 25 | endif 26 | 27 | EXTRA_DIST+=CMakeLists.txt 28 | -------------------------------------------------------------------------------- /examples/tutorial-basic.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | --- 27 | -- read_query() gets the client query before it reaches the server 28 | -- 29 | -- @param packet the mysql-packet sent by client 30 | -- 31 | -- the packet contains a command-packet: 32 | -- * the first byte the type (e.g. proxy.COM_QUERY) 33 | -- * the argument of the command 34 | -- 35 | -- http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#Command_Packet 36 | -- 37 | -- for a COM_QUERY it is the query itself in plain-text 38 | -- 39 | function read_query( packet ) 40 | print("read hello world") 41 | if string.byte(packet) == proxy.COM_QUERY then 42 | print("we got a normal query: " .. string.sub(packet, 2)) 43 | end 44 | print("default_charset is: " .. proxy.connection.client.default_charset) 45 | proxy.queries:append(1, packet, { resultset_is_needed = true}) 46 | return proxy.PROXY_SEND_QUERY 47 | end 48 | function read_query_result( inj ) 49 | print("hellowrold!!") 50 | print("client charset is: " .. proxy.connection.client.default_charset) 51 | print("server charset is: " .. proxy.connection.server.default_charset) 52 | end 53 | 54 | -------------------------------------------------------------------------------- /examples/tutorial-constants.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | -- we need at least 0.5.1 27 | assert(proxy.PROXY_VERSION >= 0x00501, "you need at least mysql-proxy 0.5.1 to run this module") 28 | 29 | --- 30 | -- read_query() gets the client query before it reaches the server 31 | -- 32 | -- @param packet the mysql-packet sent by client 33 | -- 34 | -- we have several constants defined, e.g.: 35 | -- * _VERSION 36 | -- 37 | -- * proxy.PROXY_VERSION 38 | -- * proxy.COM_* 39 | -- * proxy.MYSQL_FIELD_* 40 | -- 41 | function read_query( packet ) 42 | if packet:byte() == proxy.COM_QUERY then 43 | print("get got a Query: " .. packet:sub(2)) 44 | 45 | -- proxy.PROXY_VERSION is the proxy version as HEX number 46 | -- 0x00501 is 0.5.1 47 | print("we are: " .. string.format("%05x", proxy.PROXY_VERSION)) 48 | print("lua is: " .. _VERSION) 49 | end 50 | end 51 | 52 | -------------------------------------------------------------------------------- /examples/tutorial-inject.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | --- 27 | -- read_query() can rewrite packets 28 | -- 29 | -- You can use read_query() to replace the packet sent by the client and rewrite 30 | -- query as you like 31 | -- 32 | -- @param packet the mysql-packet sent by the client 33 | -- 34 | -- @return 35 | -- * nothing to pass on the packet as is, 36 | -- * proxy.PROXY_SEND_QUERY to send the queries from the proxy.queries queue 37 | -- * proxy.PROXY_SEND_RESULT to send your own result-set 38 | -- 39 | function read_query( packet ) 40 | if string.byte(packet) == proxy.COM_QUERY then 41 | print("we got a normal query: " .. string.sub(packet, 2)) 42 | 43 | proxy.queries:append(1, packet ) 44 | -- generate a new COM_QUERY packet 45 | -- [ \3SELECT NOW() ] 46 | -- and inject it with the id = 2 47 | proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()", { resultset_is_needed = true } ) 48 | 49 | return proxy.PROXY_SEND_QUERY 50 | end 51 | end 52 | 53 | --- 54 | -- read_query_result() is called when we receive a query result 55 | -- from the server 56 | -- 57 | -- we can analyze the response, drop the response and pass it on (default) 58 | -- 59 | -- as we injected a SELECT NOW() above, we don't want to tell the client about it 60 | -- and drop the result with proxy.PROXY_IGNORE_RESULT 61 | -- 62 | -- @return 63 | -- * nothing or proxy.PROXY_SEND_RESULT to pass the result-set to the client 64 | -- * proxy.PROXY_IGNORE_RESULT to drop the result-set 65 | -- 66 | function read_query_result(inj) 67 | print("injected result-set: id = " .. inj.id) 68 | 69 | -- inj.id = 2 was assigned above in the proxy.queries:append() 70 | -- 71 | -- drop the resultset when we are done to hide it from the client 72 | -- (in lua the first index is 1, not 0) 73 | if (inj.id == 2) then 74 | for row in inj.resultset.rows do 75 | print("injected query returned: " .. row[1]) 76 | end 77 | 78 | return proxy.PROXY_IGNORE_RESULT 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /examples/tutorial-prep-stmts.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | local proto = require("mysql.proto") 22 | 23 | local prep_stmts = { } 24 | 25 | function read_query( packet ) 26 | local cmd_type = packet:byte() 27 | if cmd_type == proxy.COM_STMT_PREPARE then 28 | proxy.queries:append(1, packet, { resultset_is_needed = true } ) 29 | return proxy.PROXY_SEND_QUERY 30 | elseif cmd_type == proxy.COM_STMT_EXECUTE then 31 | proxy.queries:append(2, packet, { resultset_is_needed = true } ) 32 | return proxy.PROXY_SEND_QUERY 33 | elseif cmd_type == proxy.COM_STMT_CLOSE then 34 | proxy.queries:append(3, packet, { resultset_is_needed = true } ) 35 | return proxy.PROXY_SEND_QUERY 36 | end 37 | end 38 | 39 | function read_query_result(inj) 40 | if inj.id == 1 then 41 | -- print the query we sent 42 | local stmt_prepare = assert(proto.from_stmt_prepare_packet(inj.query)) 43 | print(("> PREPARE: %s"):format(stmt_prepare.stmt_text)) 44 | 45 | -- and the stmt-id we got for it 46 | if inj.resultset.raw:byte() == 0 then 47 | local stmt_prepare_ok = assert(proto.from_stmt_prepare_ok_packet(inj.resultset.raw)) 48 | print(("< PREPARE: stmt-id = %d (resultset-cols = %d, params = %d)"):format( 49 | stmt_prepare_ok.stmt_id, 50 | stmt_prepare_ok.num_columns, 51 | stmt_prepare_ok.num_params)) 52 | 53 | prep_stmts[stmt_prepare_ok.stmt_id] = { 54 | num_columns = stmt_prepare_ok.num_columns, 55 | num_params = stmt_prepare_ok.num_params, 56 | } 57 | end 58 | elseif inj.id == 2 then 59 | local stmt_id = assert(proto.stmt_id_from_stmt_execute_packet(inj.query)) 60 | local stmt_execute = assert(proto.from_stmt_execute_packet(inj.query, prep_stmts[stmt_id].num_params)) 61 | print(("> EXECUTE: stmt-id = %d"):format(stmt_execute.stmt_id)) 62 | if stmt_execute.new_params_bound then 63 | for ndx, v in ipairs(stmt_execute.params) do 64 | print((" [%d] %s (type = %d)"):format(ndx, tostring(v.value), v.type)) 65 | end 66 | end 67 | elseif inj.id == 3 then 68 | local stmt_close = assert(proto.from_stmt_close_packet(inj.query)) 69 | print(("> CLOSE: stmt-id = %d"):format(stmt_close.stmt_id)) 70 | 71 | prep_stmts[stmt_close.stmt_id] = nil -- cleanup 72 | end 73 | end 74 | 75 | -------------------------------------------------------------------------------- /examples/tutorial-query-time.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | --- 27 | -- getting the query time 28 | -- 29 | -- each injected query we send to the server has a start and end-time 30 | -- 31 | -- * start-time: when we call proxy.queries:append() 32 | -- * end-time: when we received the full result-set 33 | -- 34 | -- @param packet the mysql-packet sent by the client 35 | -- 36 | -- @return 37 | -- * proxy.PROXY_SEND_QUERY to send the queries from the proxy.queries queue 38 | -- 39 | function read_query( packet ) 40 | if packet:byte() == proxy.COM_QUERY then 41 | print("we got a normal query: " .. packet:sub(2)) 42 | 43 | proxy.queries:append(1, packet, { resultset_is_needed = false} ) 44 | 45 | return proxy.PROXY_SEND_QUERY 46 | end 47 | end 48 | 49 | --- 50 | -- read_query_result() is called when we receive a query result 51 | -- from the server 52 | -- 53 | -- inj.query_time is the query-time in micro-seconds 54 | -- 55 | -- @return 56 | -- * nothing or proxy.PROXY_SEND_RESULT to pass the result-set to the client 57 | -- 58 | function read_query_result(inj) 59 | print("query-time: " .. (inj.query_time / 1000) .. "ms") 60 | print("response-time: " .. (inj.response_time / 1000) .. "ms") 61 | end 62 | -------------------------------------------------------------------------------- /examples/tutorial-resultset.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | -- init the query-counter if it isn't done yet 27 | if not proxy.global.query_counter then 28 | proxy.global.query_counter = 0 29 | end 30 | 31 | local query_counter = 0 32 | 33 | --- 34 | -- read_query() can return a resultset 35 | -- 36 | -- You can use read_query() to return a result-set. 37 | -- 38 | -- @param packet the mysql-packet sent by the client 39 | -- 40 | -- @return 41 | -- * nothing to pass on the packet as is, 42 | -- * proxy.PROXY_SEND_QUERY to send the queries from the proxy.queries queue 43 | -- * proxy.PROXY_SEND_RESULT to send your own result-set 44 | -- 45 | function read_query( packet ) 46 | -- a new query came in in this connection 47 | proxy.global.query_counter = proxy.global.query_counter + 1 48 | query_counter = query_counter + 1 49 | 50 | if string.byte(packet) == proxy.COM_QUERY then 51 | --[[ 52 | 53 | we use a simple string-match to split commands are word-boundaries 54 | 55 | mysql> show querycounter 56 | 57 | is split into 58 | command = "show" 59 | option = "querycounter" 60 | 61 | spaces are ignored, the case has to be as is. 62 | 63 | mysql> show myerror 64 | 65 | returns a error-packet 66 | 67 | --]] 68 | 69 | -- try to match the string up to the first non-alphanum 70 | local f_s, f_e, command = string.find(packet, "^%s*(%w+)", 2) 71 | local option 72 | 73 | if f_e then 74 | -- if that match, take the next sub-string as option 75 | f_s, f_e, option = string.find(packet, "^%s+(%w+)", f_e + 1) 76 | end 77 | 78 | -- we got our commands, execute it 79 | if string.lower(command) == "show" and string.lower(option) == "querycounter" then 80 | --- 81 | -- proxy.PROXY_SEND_RESULT requires 82 | -- 83 | -- proxy.response.type to be either 84 | -- * proxy.MYSQLD_PACKET_OK or 85 | -- * proxy.MYSQLD_PACKET_ERR 86 | -- 87 | -- for proxy.MYSQLD_PACKET_OK you need a resultset 88 | -- * fields 89 | -- * rows 90 | -- 91 | -- for proxy.MYSQLD_PACKET_ERR 92 | -- * errmsg 93 | proxy.response.type = proxy.MYSQLD_PACKET_OK 94 | proxy.response.resultset = { 95 | fields = { 96 | { type = proxy.MYSQL_TYPE_LONG, name = "global_query_counter", }, 97 | { type = proxy.MYSQL_TYPE_LONG, name = "query_counter", }, 98 | }, 99 | rows = { 100 | { proxy.global.query_counter, query_counter } 101 | } 102 | } 103 | 104 | -- we have our result, send it back 105 | return proxy.PROXY_SEND_RESULT 106 | elseif string.lower(command) == "show" and string.lower(option) == "myerror" then 107 | proxy.response.type = proxy.MYSQLD_PACKET_ERR 108 | proxy.response.errmsg = "my first error" 109 | 110 | return proxy.PROXY_SEND_RESULT 111 | end 112 | end 113 | end 114 | 115 | 116 | -------------------------------------------------------------------------------- /examples/tutorial-rewrite.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | --- 27 | -- read_query() can rewrite packets 28 | -- 29 | -- You can use read_query() to replace the packet sent by the client and rewrite 30 | -- query as you like 31 | -- 32 | -- @param packet the mysql-packet sent by the client 33 | -- 34 | -- @return 35 | -- * nothing to pass on the packet as is, 36 | -- * proxy.PROXY_SEND_QUERY to send the queries from the proxy.queries queue 37 | -- * proxy.PROXY_SEND_RESULT to send your own result-set 38 | -- 39 | function read_query( packet ) 40 | if string.byte(packet) == proxy.COM_QUERY then 41 | local query = string.sub(packet, 2) 42 | 43 | print("we got a normal query: " .. query) 44 | 45 | -- try to match the string up to the first non-alphanum 46 | local f_s, f_e, command = string.find(packet, "^%s*(%w+)", 2) 47 | local option 48 | 49 | if f_e then 50 | -- if that match, take the next sub-string as option 51 | f_s, f_e, option = string.find(packet, "^%s+(%w+)", f_e + 1) 52 | end 53 | 54 | -- support 55 | -- 56 | -- ls [db] 57 | -- cd db 58 | -- who 59 | 60 | if command == "ls" then 61 | if option then 62 | -- FIXME: SQL INJECTION 63 | proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "SHOW TABLES FROM " .. option ) 64 | else 65 | proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "SHOW TABLES" ) 66 | end 67 | 68 | return proxy.PROXY_SEND_QUERY 69 | elseif command == "who" then 70 | proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "SHOW PROCESSLIST" ) 71 | 72 | return proxy.PROXY_SEND_QUERY 73 | elseif command == "cd" and option then 74 | proxy.queries:append(1, string.char(proxy.COM_INIT_DB) .. option ) 75 | 76 | return proxy.PROXY_SEND_QUERY 77 | end 78 | end 79 | end 80 | 81 | --- 82 | -- read_query_result() is called when we receive a query result 83 | -- from the server 84 | -- 85 | -- we can analyze the response, drop the response and pass it on (default) 86 | -- 87 | -- @return 88 | -- * nothing or proxy.PROXY_SEND_RESULT to pass the result-set to the client 89 | -- * proxy.PROXY_IGNORE_RESULT to drop the result-set 90 | -- 91 | -- @note: the function has to exist in 0.5.0 if proxy.PROXY_SEND_QUERY 92 | -- got used in read_query() 93 | -- 94 | function read_query_result(inj) 95 | 96 | end 97 | 98 | -------------------------------------------------------------------------------- /examples/tutorial-routing.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | --- 22 | -- print the socket information to all IP based routing 23 | -- 24 | -- * setup one virtual IP per backend server 25 | -- * let the proxy to all those IPs 26 | -- * create a lua-table that maps a "client.dst.name" to a backend 27 | 28 | --- 29 | -- print a address 30 | -- 31 | function address_print(prefix, address) 32 | print(("%s: %s (type = %d, address = %s, port = %d"):format(prefix, 33 | address.name or "nil", 34 | address.type or -1, 35 | address.address or "nil", 36 | address.port or -1)) -- unix-sockets don't have a port 37 | end 38 | 39 | --- 40 | -- print the address of the client side 41 | -- 42 | function connect_server() 43 | address_print("client src", proxy.connection.client.src) 44 | address_print("client dst", proxy.connection.client.dst) 45 | end 46 | 47 | --- 48 | -- print the address of the connected side and trigger a close of the connection 49 | -- 50 | function read_handshake() 51 | address_print("server src", proxy.connection.server.src) 52 | address_print("server dst", proxy.connection.server.dst) 53 | 54 | -- tell the client the server denies us 55 | proxy.response = { 56 | type = proxy.MYSQLD_PACKET_ERR, 57 | errmsg = "done" 58 | } 59 | 60 | return proxy.PROXY_SEND_RESULT 61 | end 62 | 63 | -------------------------------------------------------------------------------- /examples/tutorial-scramble.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | local password = assert(require("mysql.password")) 22 | local proto = assert(require("mysql.proto")) 23 | 24 | --- 25 | -- map usernames to another login 26 | local map_auth = { 27 | ["replace"] = { 28 | password = "me", 29 | new_user = "root", 30 | new_password = "secret" 31 | } 32 | } 33 | 34 | --- 35 | -- show how to use the mysql.password functions 36 | -- 37 | function read_auth() 38 | local c = proxy.connection.client 39 | local s = proxy.connection.server 40 | 41 | print(("for challenge %q the client sent %q"):format( 42 | s.scramble_buffer, 43 | c.scrambled_password 44 | )) 45 | 46 | -- if we know this user, replace its credentials 47 | local mapped = map_auth[c.username] 48 | 49 | if mapped and 50 | password.check( 51 | s.scramble_buffer, 52 | c.scrambled_password, 53 | password.hash(password.hash(mapped.password)) 54 | ) then 55 | 56 | proxy.queries:append(1, 57 | proto.to_response_packet({ 58 | username = mapped.new_user, 59 | response = password.scramble(s.scramble_buffer, password.hash(mapped.new_password)), 60 | charset = 8, -- default charset 61 | database = c.default_db, 62 | max_packet_size = 1 * 1024 * 1024 63 | }) 64 | ) 65 | 66 | return proxy.PROXY_SEND_QUERY 67 | end 68 | end 69 | 70 | -------------------------------------------------------------------------------- /examples/tutorial-states.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | function connect_server() 27 | print("--> a client really wants to talk to a server") 28 | end 29 | 30 | function read_handshake( ) 31 | local con = proxy.connection 32 | 33 | print("<-- let's send him some information about us") 34 | print(" mysqld-version: " .. con.server.mysqld_version) 35 | print(" thread-id : " .. con.server.thread_id) 36 | print(" scramble-buf : " .. string.format("%q", con.server.scramble_buffer)) 37 | print(" server-addr : " .. con.server.dst.address) 38 | print(" client-addr : " .. con.client.src.address) 39 | 40 | -- lets deny clients from !127.0.0.1 41 | if con.client.src.address ~= "127.0.0.1" then 42 | proxy.response.type = proxy.MYSQLD_PACKET_ERR 43 | proxy.response.errmsg = "only local connects are allowed" 44 | 45 | print("we don't like this client"); 46 | 47 | return proxy.PROXY_SEND_RESULT 48 | end 49 | end 50 | 51 | function read_auth( ) 52 | local con = proxy.connection 53 | 54 | print("--> there, look, the client is responding to the server auth packet") 55 | print(" username : " .. con.client.username) 56 | print(" password : " .. string.format("%q", con.client.scrambled_password)) 57 | print(" default_db : " .. con.client.default_db) 58 | 59 | if con.client.username == "evil" then 60 | proxy.response.type = proxy.MYSQLD_PACKET_ERR 61 | proxy.response.errmsg = "evil logins are not allowed" 62 | 63 | return proxy.PROXY_SEND_RESULT 64 | end 65 | end 66 | 67 | function read_auth_result( auth ) 68 | local state = auth.packet:byte() 69 | 70 | if state == proxy.MYSQLD_PACKET_OK then 71 | print("<-- auth ok"); 72 | elseif state == proxy.MYSQLD_PACKET_ERR then 73 | print("<-- auth failed"); 74 | else 75 | print("<-- auth ... don't know: " .. string.format("%q", auth.packet)); 76 | end 77 | end 78 | 79 | function read_query( packet ) 80 | print("--> someone sent us a query") 81 | if packet:byte() == proxy.COM_QUERY then 82 | print(" query: " .. packet:sub(2)) 83 | 84 | if packet:sub(2) == "SELECT 1" then 85 | proxy.queries:append(1, packet) 86 | end 87 | end 88 | 89 | end 90 | 91 | function read_query_result( inj ) 92 | print("<-- ... ok, this only gets called when read_query() told us") 93 | 94 | proxy.response = { 95 | type = proxy.MYSQLD_PACKET_RAW, 96 | packets = { 97 | "\255" .. 98 | "\255\004" .. -- errno 99 | "#" .. 100 | "12S23" .. 101 | "raw, raw, raw" 102 | } 103 | } 104 | 105 | return proxy.PROXY_SEND_RESULT 106 | end 107 | -------------------------------------------------------------------------------- /examples/tutorial-tokenize.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | local tokenizer = require("proxy.tokenizer") 27 | 28 | function read_query(packet) 29 | if packet:byte() == proxy.COM_QUERY then 30 | local tokens = tokenizer.tokenize(packet:sub(2)) 31 | 32 | -- just for debug 33 | for i = 1, #tokens do 34 | -- print the token and what we know about it 35 | local token = tokens[i] 36 | local txt = token["text"] 37 | if token["token_name"] == 'TK_STRING' then 38 | txt = string.format("%q", txt) 39 | end 40 | -- print(i .. ": " .. " { " .. token["token_name"] .. ", " .. token["text"] .. " }" ) 41 | print(i .. ": " .. " { " .. token["token_name"] .. ", " .. txt .. " }" ) 42 | 43 | 44 | end 45 | 46 | print("normalized query: " .. tokenizer.normalize(tokens)) 47 | print("") 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /examples/tutorial-union.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | res = { } 22 | 23 | function read_query(packet) 24 | if packet:byte() ~= proxy.COM_QUERY then return end 25 | 26 | local q = packet:sub(2) 27 | 28 | res = { } 29 | 30 | if q:sub(1, 6):upper() == "SELECT" then 31 | proxy.queries:append(1, packet, { resultset_is_needed = true }) 32 | proxy.queries:append(2, packet, { resultset_is_needed = true }) 33 | 34 | return proxy.PROXY_SEND_QUERY 35 | end 36 | end 37 | 38 | function read_query_result(inj) 39 | for row in inj.resultset.rows do 40 | res[#res + 1] = row 41 | end 42 | 43 | if inj.id ~= 2 then 44 | return proxy.PROXY_IGNORE_RESULT 45 | end 46 | 47 | proxy.response = { 48 | type = proxy.MYSQLD_PACKET_OK, 49 | resultset = { 50 | rows = res 51 | } 52 | } 53 | 54 | local fields = {} 55 | for n = 1, #inj.resultset.fields do 56 | fields[#fields + 1] = { 57 | type = inj.resultset.fields[n].type, 58 | name = inj.resultset.fields[n].name, 59 | } 60 | end 61 | 62 | proxy.response.resultset.fields = fields 63 | 64 | return proxy.PROXY_SEND_RESULT 65 | end 66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/tutorial-warnings.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | 23 | 24 | --]] 25 | 26 | --- 27 | -- read_query() can rewrite packets 28 | -- 29 | -- You can use read_query() to replace the packet sent by the client and rewrite 30 | -- query as you like 31 | -- 32 | -- @param packet the mysql-packet sent by the client 33 | -- 34 | -- @return 35 | -- * nothing to pass on the packet as is, 36 | -- * proxy.PROXY_SEND_QUERY to send the queries from the proxy.queries queue 37 | -- * proxy.PROXY_SEND_RESULT to send your own result-set 38 | -- 39 | function read_query( packet ) 40 | if string.byte(packet) == proxy.COM_QUERY then 41 | proxy.queries:append(1, packet, { resultset_is_needed = true } ) 42 | 43 | return proxy.PROXY_SEND_QUERY 44 | end 45 | end 46 | 47 | --- 48 | -- dumps the warnings of queries 49 | -- 50 | -- read_query_result() is called when we receive a query result 51 | -- from the server 52 | -- 53 | -- for all queries which pass by we check if the warning-count is > 0 and 54 | -- inject a SHOW WARNINGS and dump it to the stdout 55 | -- 56 | -- @return 57 | -- * nothing or proxy.PROXY_SEND_RESULT to pass the result-set to the client 58 | -- * proxy.PROXY_IGNORE_RESULT to drop the result-set 59 | -- 60 | function read_query_result(inj) 61 | 62 | if (inj.id == 1) then 63 | local res = assert(inj.resultset) 64 | 65 | if res.warning_count > 0 then 66 | print("Query had warnings: " .. inj.query:sub(2)) 67 | proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SHOW WARNINGS", { resultset_is_needed = true } ) 68 | end 69 | elseif (inj.id == 2) then 70 | for row in inj.resultset.rows do 71 | print(string.format("warning: [%d] %s", row[2], row[1])) 72 | end 73 | 74 | return proxy.PROXY_IGNORE_RESULT 75 | end 76 | end 77 | 78 | -------------------------------------------------------------------------------- /lib/Makefile.am: -------------------------------------------------------------------------------- 1 | luaextdir = ${pkglibdir}/lua 2 | 3 | SUBDIRS = proxy 4 | 5 | ## those are in the end examples or proof-of-concepts 6 | example_scripts = \ 7 | active-queries.lua \ 8 | active-transactions.lua \ 9 | admin-sql.lua \ 10 | analyze-query.lua \ 11 | auditing.lua \ 12 | commit-obfuscator.lua \ 13 | commit-obfuscator.msc \ 14 | histogram.lua \ 15 | load-multi.lua \ 16 | ro-balance.lua \ 17 | ro-pooling.lua \ 18 | rw-splitting.lua \ 19 | xtab.lua 20 | EXTRA_DIST = 21 | 22 | if USE_WRAPPER_SCRIPT 23 | ## only install them if we are self-contained 24 | ## otherwise let the packager decide where to put them 25 | dist_doc_DATA = ${example_scripts} 26 | else 27 | EXTRA_DIST += ${example_scripts} 28 | endif 29 | 30 | dist_luaext_DATA = \ 31 | admin.lua \ 32 | rw-splitting.lua 33 | 34 | luaext_LTLIBRARIES = lfs.la glib2.la chassis.la mysql.la lpeg.la posix.la crc32.la time.la 35 | 36 | lfs_la_SOURCES = lfs.c 37 | ## get libtool to build a shared-lib 38 | lfs_la_CPPFLAGS = ${LUA_CFLAGS} 39 | lfs_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 40 | 41 | posix_la_SOURCES = posix.c 42 | ## get libtool to build a shared-lib 43 | posix_la_CPPFLAGS = ${LUA_CFLAGS} 44 | posix_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 45 | 46 | glib2_la_SOURCES = glib2.c 47 | ## get libtool to build a shared-lib 48 | glib2_la_CPPFLAGS = ${LUA_CFLAGS} ${GLIB_CFLAGS} 49 | glib2_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 50 | glib2_la_LIBADD = $(GLIB_LIBS) 51 | 52 | chassis_la_SOURCES = chassis.c 53 | ## get libtool to build a shared-lib 54 | chassis_la_CPPFLAGS = ${LUA_CFLAGS} ${GLIB_CFLAGS} -I${top_srcdir}/src/ 55 | chassis_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 56 | chassis_la_LIBADD = ${GLIB_LIBS} ${top_builddir}/src/libmysql-chassis.la 57 | 58 | crc32_la_SOURCES = \ 59 | crc32.c \ 60 | crc32-lua.c 61 | ## get libtool to build a shared-lib 62 | crc32_la_CPPFLAGS = ${LUA_CFLAGS} ${GLIB_CFLAGS} -I${top_srcdir}/src/ 63 | crc32_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 64 | crc32_la_LIBADD = $(GLIB_LIBS) 65 | 66 | mysql_la_SOURCES = \ 67 | mysql-proto.c \ 68 | mysql-password.c \ 69 | sql-tokenizer.l \ 70 | sql-tokenizer-tokens.c \ 71 | sql-tokenizer-keywords.c \ 72 | sql-tokenizer-lua.c 73 | ## get libtool to build a shared-lib 74 | mysql_la_CPPFLAGS = ${LUA_CFLAGS} ${GLIB_CFLAGS} -I${top_srcdir}/src/ ${MYSQL_CFLAGS} -I${top_builddir}/lib/ 75 | mysql_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 76 | mysql_la_LIBADD = ${GLIB_LIBS} ${top_builddir}/src/libmysql-proxy.la 77 | 78 | time_la_SOURCES = \ 79 | time-ticker-lua.c 80 | ## get libtool to build a shared-lib 81 | time_la_CPPFLAGS = ${LUA_CFLAGS} -I${top_srcdir}/src/ 82 | time_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 83 | 84 | lpeg_la_SOURCES = lpeg.c 85 | lpeg_la_CPPFLAGS = ${LUA_CFLAGS} 86 | lpeg_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version 87 | 88 | 89 | noinst_HEADERS = \ 90 | sql-tokenizer.h \ 91 | sql-tokenizer-keywords.h \ 92 | crc32.h 93 | 94 | EXTRA_DIST += \ 95 | glib2.def \ 96 | lfs.def \ 97 | chassis.def \ 98 | lpeg.def \ 99 | mysql.def \ 100 | posix.def \ 101 | CMakeLists.txt 102 | 103 | DISTCLEANFILES = \ 104 | sql-tokenizer.c \ 105 | sql-tokenizer-keywords.c 106 | 107 | noinst_PROGRAMS=sql-tokenizer-gen 108 | 109 | sql_tokenizer_gen_SOURCES=\ 110 | sql-tokenizer-gen.c \ 111 | sql-tokenizer-tokens.c 112 | 113 | sql_tokenizer_gen_CPPFLAGS=${GLIB_CFLAGS} -I${srcdir} 114 | sql_tokenizer_gen_LDADD=${GLIB_LIBS} 115 | 116 | sql-tokenizer.c: sql-tokenizer-keywords.c 117 | 118 | sql-tokenizer-keywords.c: sql-tokenizer-gen 119 | ${builddir}/sql-tokenizer-gen > ${builddir}/sql-tokenizer-keywords.c 120 | -------------------------------------------------------------------------------- /lib/active-transactions.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | --[[ 21 | 22 | print the statements of all transactions as soon as one of them aborted 23 | 24 | for now we know about: 25 | * Lock wait timeout exceeded 26 | * Deadlock found when trying to get lock 27 | 28 | --]] 29 | 30 | if not proxy.global.trxs then 31 | proxy.global.trxs = { } 32 | end 33 | 34 | function read_query(packet) 35 | if packet:byte() ~= proxy.COM_QUERY then return end 36 | 37 | if not proxy.global.trxs[proxy.connection.server.thread_id] then 38 | proxy.global.trxs[proxy.connection.server.thread_id] = { } 39 | end 40 | 41 | proxy.queries:append(1, packet, { resultset_is_needed = true }) 42 | 43 | local t = proxy.global.trxs[proxy.connection.server.thread_id] 44 | 45 | t[#t + 1] = packet:sub(2) 46 | 47 | return proxy.PROXY_SEND_QUERY 48 | end 49 | 50 | function read_query_result(inj) 51 | local res = inj.resultset 52 | local flags = res.flags 53 | 54 | if res.query_status == proxy.MYSQLD_PACKET_ERR then 55 | local err_code = res.raw:byte(2) + (res.raw:byte(3) * 256) 56 | local err_sqlstate = res.raw:sub(5, 9) 57 | local err_msg = res.raw:sub(10) 58 | -- print("-- error-packet: " .. err_code) 59 | 60 | if err_code == 1205 or -- Lock wait timeout exceeded 61 | err_code == 1213 then -- Deadlock found when trying to get lock 62 | print(("[%d] received a ERR(%d, %s), dumping all active transactions"):format( 63 | proxy.connection.server.thread_id, 64 | err_code, 65 | err_msg)) 66 | 67 | for thread_id, statements in pairs(proxy.global.trxs) do 68 | for stmt_id, statement in ipairs(statements) do 69 | print((" [%d].%d: %s"):format(thread_id, stmt_id, statement)) 70 | end 71 | end 72 | end 73 | end 74 | 75 | -- we are done, free the statement list 76 | if not flags.in_trans then 77 | proxy.global.trxs[proxy.connection.server.thread_id] = nil 78 | end 79 | end 80 | 81 | function disconnect_client() 82 | proxy.global.trxs[proxy.connection.server.thread_id] = nil 83 | end 84 | 85 | -------------------------------------------------------------------------------- /lib/admin-bak.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | -- redefine next, used for iterate userdata 22 | rawnext = next 23 | function next(t,k) 24 | local m = getmetatable(t) 25 | local n = m and m.__next or rawnext 26 | return n(t,k) 27 | end 28 | 29 | function set_error(errmsg) 30 | proxy.response = { 31 | type = proxy.MYSQLD_PACKET_ERR, 32 | errmsg = errmsg or "error" 33 | } 34 | end 35 | 36 | function read_query(packet) 37 | if packet:byte() ~= proxy.COM_QUERY then 38 | set_error("[admin] we only handle text-based queries (COM_QUERY)") 39 | return proxy.PROXY_SEND_RESULT 40 | end 41 | 42 | local query = packet:sub(2) 43 | 44 | local rows = { } 45 | local fields = { } 46 | 47 | if query:lower() == "select * from backends" then 48 | fields = { 49 | { name = "backend_ndx", 50 | type = proxy.MYSQL_TYPE_LONG }, 51 | { name = "username", 52 | type = proxy.MYSQL_TYPE_STRING }, 53 | { name = "address", 54 | type = proxy.MYSQL_TYPE_STRING }, 55 | { name = "state", 56 | type = proxy.MYSQL_TYPE_STRING }, 57 | { name = "type", 58 | type = proxy.MYSQL_TYPE_STRING }, 59 | { name = "uuid", 60 | type = proxy.MYSQL_TYPE_STRING }, 61 | { name = "connected_clients", 62 | type = proxy.MYSQL_TYPE_LONG }, 63 | { name = "cur_idle_connections", 64 | type = proxy.MYSQL_TYPE_LONG }, 65 | } 66 | 67 | for i = 1, #proxy.global.backends do 68 | local states = { 69 | "unknown", 70 | "up", 71 | "down" 72 | } 73 | local types = { 74 | "unknown", 75 | "rw", 76 | "ro" 77 | } 78 | local b = proxy.global.backends[i] 79 | for j, username in next, b.pool.users, 0 do 80 | 81 | rows[#rows + 1] = { 82 | i, 83 | username, 84 | b.dst.name, -- configured backend address 85 | states[b.state + 1], -- the C-id is pushed down starting at 0 86 | types[b.type + 1], -- the C-id is pushed down starting at 0 87 | b.uuid, -- the MySQL Server's UUID if it is managed 88 | b.connected_clients, -- currently connected clients 89 | b.pool.users[username].cur_idle_connections 90 | } 91 | end 92 | end 93 | elseif query:lower() == "select * from help" then 94 | fields = { 95 | { name = "command", 96 | type = proxy.MYSQL_TYPE_STRING }, 97 | { name = "description", 98 | type = proxy.MYSQL_TYPE_STRING }, 99 | } 100 | rows[#rows + 1] = { "SELECT * FROM help", "shows this help" } 101 | rows[#rows + 1] = { "SELECT * FROM backends", "lists the backends and their state" } 102 | else 103 | set_error("use 'SELECT * FROM help' to see the supported commands") 104 | return proxy.PROXY_SEND_RESULT 105 | end 106 | 107 | proxy.response = { 108 | type = proxy.MYSQLD_PACKET_OK, 109 | resultset = { 110 | fields = fields, 111 | rows = rows 112 | } 113 | } 114 | return proxy.PROXY_SEND_RESULT 115 | end 116 | -------------------------------------------------------------------------------- /lib/auditing.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | local user = "" 22 | 23 | function read_handshake( ) 24 | local con = proxy.connection 25 | 26 | print("<-- let's send him some information about us") 27 | print(" server-addr : " .. con.server.dst.name) 28 | print(" client-addr : " .. con.client.src.name) 29 | end 30 | 31 | function read_auth( ) 32 | local con = proxy.connection 33 | 34 | print("--> there, look, the client is responding to the server auth packet") 35 | print(" username : " .. con.client.username) 36 | 37 | user = con.client.username 38 | end 39 | 40 | function read_auth_result( auth ) 41 | local state = auth.packet:byte() 42 | 43 | if state == proxy.MYSQLD_PACKET_OK then 44 | print("<-- auth ok"); 45 | elseif state == proxy.MYSQLD_PACKET_ERR then 46 | print("<-- auth failed"); 47 | else 48 | print("<-- auth ... don't know: " .. string.format("%q", auth.packet)); 49 | end 50 | end 51 | 52 | function read_query( packet ) 53 | print("--> '".. user .."' sent us a query") 54 | if packet:byte() == proxy.COM_QUERY then 55 | print(" query: " .. packet:sub(2)) 56 | end 57 | end 58 | 59 | 60 | -------------------------------------------------------------------------------- /lib/chassis.def: -------------------------------------------------------------------------------- 1 | LIBRARY chassis.dll 2 | EXPORTS 3 | luaopen_chassis 4 | -------------------------------------------------------------------------------- /lib/commit-obfuscator.lua: -------------------------------------------------------------------------------- 1 | --[[ $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ --]] 20 | 21 | --[[ 22 | 23 | Let a random number of transaction rollback 24 | 25 | As part of the QA we have to verify that applications handle 26 | rollbacks nicely. To simulate a deadlock we turn client-side COMMITs 27 | into server-side ROLLBACKs and return a ERROR packet to the client 28 | telling it a deadlock happened. 29 | 30 | --]] 31 | 32 | function read_query(packet) 33 | if packet:byte() ~= proxy.COM_QUERY then return end 34 | 35 | -- only care about commits 36 | if packet:sub(2):upper() ~= "COMMIT" then return end 37 | 38 | -- let 80% fail 39 | if math.random(10) <= 5 then return end 40 | 41 | proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "ROLLBACK", { resultset_is_needed = true }) 42 | 43 | return proxy.PROXY_SEND_QUERY 44 | end 45 | 46 | function read_query_result(inj) 47 | if inj.id ~= 1 then return end 48 | 49 | proxy.response = { 50 | type = proxy.MYSQLD_PACKET_ERR, 51 | errmsg = "Lock wait timeout exceeded; try restarting transaction", 52 | errno = 1205, 53 | sqlstate = "HY000" 54 | } 55 | 56 | return proxy.PROXY_SEND_RESULT 57 | end 58 | 59 | -------------------------------------------------------------------------------- /lib/commit-obfuscator.msc: -------------------------------------------------------------------------------- 1 | msc { 2 | client, proxy, server; 3 | 4 | client->proxy [ label = "COMMIT" ]; 5 | proxy->server [ label = "ROLLBACK" ]; 6 | server->proxy [ label = "OK" ]; 7 | proxy->client [ label = "ERR: deadlock" ]; 8 | } 9 | -------------------------------------------------------------------------------- /lib/crc32-lua.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2011, Qihoo 360 - Chancey, wangchao3@360.cn 3 | 4 | $%ENDLICENSE%$ */ 5 | #include 6 | #include 7 | #include "lua-env.h" 8 | #include "crc32.h" 9 | #include "glib-ext.h" 10 | 11 | int crc32_string(lua_State *L) { 12 | size_t str_len; 13 | const char *str = luaL_checklstring(L, 1, &str_len); 14 | g_debug("string:%s, length:%d", str, str_len); 15 | // crc32 hash 16 | unsigned int key = crc32(str, str_len); 17 | g_debug("crc key:%ld", key); 18 | 19 | // push crc number 20 | lua_pushnumber(L, key); 21 | 22 | return 1; 23 | } 24 | 25 | /* 26 | ** Assumes the table is on top of the stack. 27 | */ 28 | static void set_info (lua_State *L) { 29 | lua_pushliteral (L, "_COPYRIGHT"); 30 | lua_pushliteral (L, "Copyright (C) 2011 Qihoo 360 - wangchao3"); 31 | lua_settable (L, -3); 32 | lua_pushliteral (L, "_DESCRIPTION"); 33 | lua_pushliteral (L, "CRC32 String for Proxy.*"); 34 | lua_settable (L, -3); 35 | lua_pushliteral (L, "_VERSION"); 36 | lua_pushliteral (L, "LuaCRC32string 0.1"); 37 | lua_settable (L, -3); 38 | } 39 | 40 | 41 | static const struct luaL_reg crc32_m[] = { 42 | {"crc32", crc32_string}, 43 | {NULL, NULL}, 44 | }; 45 | 46 | #if defined(_WIN32) 47 | # define LUAEXT_API __declspec(dllexport) 48 | #else 49 | # define LUAEXT_API extern 50 | #endif 51 | 52 | LUAEXT_API int luaopen_crc32_string(lua_State *L) { 53 | luaL_register (L, "crc32", crc32_m); 54 | set_info (L); 55 | return 1; 56 | } 57 | -------------------------------------------------------------------------------- /lib/crc32.c: -------------------------------------------------------------------------------- 1 | #include "crc32.h" 2 | 3 | unsigned long crc32(const unsigned char *p, unsigned int nr) 4 | { 5 | unsigned int len; 6 | uint32_t crcinit = 0; 7 | uint32_t crc = crcinit^0xFFFFFFFF; 8 | 9 | for (len =+nr; nr--; ++p) { 10 | crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*p)) & 0xFF ]; 11 | } 12 | 13 | return crc^0xFFFFFFFF;; 14 | } 15 | -------------------------------------------------------------------------------- /lib/crc32.h: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | * This code implements the AUTODIN II polynomial 4 | * The variable corresponding to the macro argument "crc" should 5 | * be an unsigned long. 6 | * Oroginal code by Spencer Garrett 7 | */ 8 | 9 | /* generated using the AUTODIN II polynomial 10 | * x^32 + x^26 + x^23 + x^22 + x^16 + 11 | * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 12 | */ 13 | 14 | static const unsigned int crc32tab[256] = { 15 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 16 | 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 17 | 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 18 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 19 | 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 20 | 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 21 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 22 | 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 23 | 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 24 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 25 | 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 26 | 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 27 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 28 | 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 29 | 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 30 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 31 | 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 32 | 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 33 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 34 | 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 35 | 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 36 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 37 | 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 38 | 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 39 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 40 | 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 41 | 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 42 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 43 | 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 44 | 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 45 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 46 | 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 47 | 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 48 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 49 | 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 50 | 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 51 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 52 | 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 53 | 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 54 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 55 | 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 56 | 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 57 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 58 | 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 59 | 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 60 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 61 | 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 62 | 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 63 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 64 | 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 65 | 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 66 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 67 | 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 68 | 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 69 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 70 | 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 71 | 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 72 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 73 | 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 74 | 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 75 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 76 | 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 77 | 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 78 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 79 | }; 80 | 81 | -------------------------------------------------------------------------------- /lib/glib2.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | static int lua_g_usleep (lua_State *L) { 29 | int ms = luaL_checkinteger (L, 1); 30 | 31 | g_usleep(ms); 32 | 33 | return 0; 34 | } 35 | 36 | static int lua_g_get_current_time (lua_State *L) { 37 | GTimeVal t; 38 | 39 | g_get_current_time(&t); 40 | 41 | lua_newtable(L); 42 | lua_pushinteger(L, t.tv_sec); 43 | lua_setfield(L, -2, "tv_sec"); 44 | lua_pushinteger(L, t.tv_usec); 45 | lua_setfield(L, -2, "tv_usec"); 46 | 47 | return 1; 48 | } 49 | 50 | static int lua_g_checksum_md5 (lua_State *L) { 51 | size_t str_len; 52 | const char *str = luaL_checklstring (L, 1, &str_len); 53 | GChecksum *cs; 54 | 55 | cs = g_checksum_new(G_CHECKSUM_MD5); 56 | 57 | g_checksum_update(cs, (guchar *)str, str_len); 58 | 59 | lua_pushstring(L, g_checksum_get_string(cs)); 60 | 61 | g_checksum_free(cs); 62 | 63 | return 1; 64 | } 65 | 66 | /* 67 | ** Assumes the table is on top of the stack. 68 | */ 69 | static void set_info (lua_State *L) { 70 | lua_pushliteral (L, "_COPYRIGHT"); 71 | lua_pushliteral (L, "Copyright (c) 2010 Oracle"); 72 | lua_settable (L, -3); 73 | lua_pushliteral (L, "_DESCRIPTION"); 74 | lua_pushliteral (L, "export glib2-functions as glib.*"); 75 | lua_settable (L, -3); 76 | lua_pushliteral (L, "_VERSION"); 77 | lua_pushliteral (L, "LuaGlib2 0.1"); 78 | lua_settable (L, -3); 79 | } 80 | 81 | 82 | static const struct luaL_reg gliblib[] = { 83 | {"usleep", lua_g_usleep}, 84 | {"md5", lua_g_checksum_md5}, 85 | {"get_current_time", lua_g_get_current_time}, 86 | {NULL, NULL}, 87 | }; 88 | 89 | #if defined(_WIN32) 90 | # define LUAEXT_API __declspec(dllexport) 91 | #else 92 | # define LUAEXT_API extern 93 | #endif 94 | 95 | LUAEXT_API int luaopen_glib2 (lua_State *L) { 96 | luaL_register (L, "glib2", gliblib); 97 | set_info (L); 98 | return 1; 99 | } 100 | -------------------------------------------------------------------------------- /lib/glib2.def: -------------------------------------------------------------------------------- 1 | LIBRARY glib2.dll 2 | EXPORTS 3 | luaopen_glib2 4 | -------------------------------------------------------------------------------- /lib/lfs.def: -------------------------------------------------------------------------------- 1 | LIBRARY lfs.dll 2 | EXPORTS 3 | luaopen_lfs 4 | -------------------------------------------------------------------------------- /lib/lpeg.def: -------------------------------------------------------------------------------- 1 | LIBRARY lpeg.dll 2 | EXPORTS 3 | luaopen_lpeg 4 | -------------------------------------------------------------------------------- /lib/mysql.def: -------------------------------------------------------------------------------- 1 | LIBRARY mysql.dll 2 | EXPORTS 3 | luaopen_mysql_proto 4 | -------------------------------------------------------------------------------- /lib/posix.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 MySQL AB */ 2 | 3 | #ifdef HAVE_CONFIG_H 4 | #include "config.h" 5 | #endif 6 | 7 | #include 8 | #include 9 | 10 | #ifdef HAVE_PWD_H 11 | #include 12 | #endif 13 | 14 | #ifdef HAVE_SIGNAL_H 15 | #include 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | static int lua_getpid (lua_State *L) { 23 | lua_pushinteger (L, getpid()); 24 | 25 | return 1; 26 | } 27 | 28 | static int lua_getuid (lua_State *L) { 29 | lua_pushinteger (L, getuid()); 30 | 31 | return 1; 32 | } 33 | 34 | #ifdef HAVE_SIGNAL_H 35 | static int lua_kill (lua_State *L) { 36 | pid_t pid = luaL_checkinteger (L, 1); 37 | int sig = luaL_checkinteger (L, 2); 38 | 39 | lua_pushinteger(L, kill(pid, sig)); 40 | 41 | return 1; 42 | } 43 | #endif 44 | 45 | #ifdef HAVE_PWD_H 46 | static int lua_getpwuid(lua_State *L) { 47 | struct passwd *p; 48 | int uid = luaL_checkinteger (L, 1); 49 | 50 | if (NULL == (p = getpwuid( (uid_t)uid )) ) { 51 | lua_pushnil(L); 52 | return 1; 53 | } 54 | 55 | lua_newtable (L); 56 | lua_pushstring (L, "name"); 57 | lua_pushstring (L, p->pw_name); 58 | lua_settable (L, -3); 59 | lua_pushstring (L, "uid"); 60 | lua_pushinteger (L, p->pw_uid); 61 | lua_settable (L, -3); 62 | lua_pushstring (L, "gid"); 63 | lua_pushinteger (L, p->pw_gid); 64 | lua_settable (L, -3); 65 | lua_pushstring (L, "dir"); 66 | lua_pushstring (L, p->pw_dir); 67 | lua_settable (L, -3); 68 | lua_pushstring (L, "shell"); 69 | lua_pushstring (L, p->pw_shell); 70 | lua_settable (L, -3); 71 | 72 | return 1; 73 | } 74 | #endif 75 | 76 | /* 77 | ** Assumes the table is on top of the stack. 78 | */ 79 | static void set_info (lua_State *L) { 80 | lua_pushliteral (L, "_COPYRIGHT"); 81 | lua_pushliteral (L, "Copyright (C) 2008-2010 Oracle Inc"); 82 | lua_settable (L, -3); 83 | lua_pushliteral (L, "_DESCRIPTION"); 84 | lua_pushliteral (L, "export posix-functions as posix.*"); 85 | lua_settable (L, -3); 86 | lua_pushliteral (L, "_VERSION"); 87 | lua_pushliteral (L, "LuaPosix 0.1"); 88 | lua_settable (L, -3); 89 | } 90 | 91 | 92 | static const struct luaL_reg posixlib[] = { 93 | {"getpid", lua_getpid}, 94 | {"getuid", lua_getuid}, 95 | #ifdef HAVE_PWD_H 96 | {"getpwuid", lua_getpwuid}, 97 | #endif 98 | #ifdef HAVE_SIGNAL_H 99 | {"kill", lua_kill}, 100 | #endif 101 | {NULL, NULL}, 102 | }; 103 | 104 | #if defined(_WIN32) 105 | # define LUAEXT_API __declspec(dllexport) 106 | #else 107 | # define LUAEXT_API extern 108 | #endif 109 | 110 | LUAEXT_API int luaopen_posix (lua_State *L) { 111 | luaL_register (L, "posix", posixlib); 112 | set_info (L); 113 | return 1; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /lib/posix.def: -------------------------------------------------------------------------------- 1 | LIBRARY posix.dll 2 | EXPORTS 3 | luaopen_posix 4 | -------------------------------------------------------------------------------- /lib/proxy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INSTALL(FILES 2 | auto-config.lua 3 | balance.lua 4 | commands.lua 5 | parser.lua 6 | tokenizer.lua 7 | test.lua 8 | charset.lua 9 | crc32.lua 10 | filter.lua 11 | log.lua 12 | split.lua 13 | auth.lua 14 | 15 | DESTINATION lib/mysql-proxy/lua/proxy/ 16 | ) 17 | -------------------------------------------------------------------------------- /lib/proxy/Makefile.am: -------------------------------------------------------------------------------- 1 | luaextdir = ${pkglibdir}/lua/ 2 | 3 | pkglib_proxydir = $(luaextdir)/proxy 4 | dist_pkglib_proxy_DATA = \ 5 | auto-config.lua \ 6 | balance.lua \ 7 | commands.lua \ 8 | parser.lua \ 9 | tokenizer.lua \ 10 | test.lua \ 11 | charset.lua \ 12 | crc32.lua \ 13 | filter.lua \ 14 | log.lua \ 15 | split.lua \ 16 | auth.lua \ 17 | ticker.lua 18 | 19 | EXTRA_DIST=CMakeLists.txt 20 | -------------------------------------------------------------------------------- /lib/proxy/auth.lua: -------------------------------------------------------------------------------- 1 | module("proxy.auth", package.seeall) 2 | 3 | local config_file = string.format("proxy.conf.config_%s", proxy.global.config.instance) 4 | local auth_ip = require(config_file).auth 5 | local lvs_ip = require(config_file).lvs_ip 6 | local seg_ip = require(config_file).seg_ip 7 | 8 | function allow_ip(ip) 9 | for i = 1, #auth_ip do 10 | if ip == auth_ip[i].ip then 11 | return true 12 | end 13 | end 14 | for i = 1, #lvs_ip do 15 | if ip == lvs_ip[i] then 16 | return true 17 | end 18 | end 19 | for i = 1, #seg_ip do 20 | if ip:find(seg_ip[i]) == 1 then 21 | return true 22 | end 23 | end 24 | return false 25 | end 26 | -------------------------------------------------------------------------------- /lib/proxy/balance.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/lib/proxy/balance.lua -------------------------------------------------------------------------------- /lib/proxy/charset.lua: -------------------------------------------------------------------------------- 1 | module("proxy.charset", package.seeall) 2 | 3 | local config_file = string.format("proxy.conf.config_%s", proxy.global.config.instance) 4 | local config = require(config_file) 5 | local log = require("proxy.log") 6 | local level = log.level 7 | local write_log = log.write_log 8 | 9 | function modify_charset(tokens, c, s) 10 | write_log(level.DEBUG, "ENTER MODIFY_CHARSET") 11 | 12 | local is_set_client = false 13 | local is_set_results = false 14 | local is_set_connection = false 15 | 16 | if tokens and tokens[1].text:upper() == "SET" then 17 | if #tokens >=3 then 18 | local token2 = tokens[2].text:upper() 19 | if token2 == "NAMES" then 20 | is_set_client = true 21 | is_set_results = true 22 | is_set_connection = true 23 | elseif #tokens == 4 and tokens[3].text == "=" then 24 | if token2 == "CHARACTER_SET_CLIENT" then 25 | is_set_client = true 26 | elseif token2 == "CHARACTER_SET_RESULTS" then 27 | is_set_results = true 28 | elseif token2 == "CHARACTER_SET_CONNECTION" then 29 | is_set_connection = true 30 | end 31 | end 32 | end 33 | end 34 | 35 | local id = 2 36 | local default_charset = "LATIN1" 37 | 38 | if not is_set_client and c.charset_client ~= s.charset_client then 39 | id = id + 1 40 | if c.charset_client == "" then 41 | proxy.queries:prepend(id, string.char(proxy.COM_QUERY) .. "SET CHARACTER_SET_CLIENT=" .. default_charset, { resultset_is_needed = true }) 42 | write_log(level.INFO, "change s.charset_client to ", default_charset) 43 | else 44 | proxy.queries:prepend(id, string.char(proxy.COM_QUERY) .. "SET CHARACTER_SET_CLIENT=" .. c.charset_client, { resultset_is_needed = true }) 45 | write_log(level.INFO, "change s.charset_client to ", c.charset_client) 46 | end 47 | end 48 | 49 | if not is_set_results and c.charset_results ~= s.charset_results then 50 | id = id + 1 51 | if c.charset_results == "" then 52 | proxy.queries:prepend(id, string.char(proxy.COM_QUERY) .. "SET CHARACTER_SET_RESULTS=" .. default_charset, { resultset_is_needed = true }) 53 | write_log(level.INFO, "change s.charset_results to ", default_charset) 54 | else 55 | proxy.queries:prepend(id, string.char(proxy.COM_QUERY) .. "SET CHARACTER_SET_RESULTS=" .. c.charset_results, { resultset_is_needed = true }) 56 | write_log(level.INFO, "change s.charset_results to ", c.charset_results) 57 | end 58 | end 59 | 60 | if not is_set_connection and c.charset_connection ~= s.charset_connection then 61 | id = id + 1 62 | if c.charset_connection == "" then 63 | proxy.queries:prepend(id, string.char(proxy.COM_QUERY) .. "SET CHARACTER_SET_CONNECTION=" .. default_charset, { resultset_is_needed = true }) 64 | write_log(level.INFO, "change s.charset_connection to ", default_charset) 65 | else 66 | proxy.queries:prepend(id, string.char(proxy.COM_QUERY) .. "SET CHARACTER_SET_CONNECTION=" .. c.charset_connection, { resultset_is_needed = true }) 67 | write_log(level.INFO, "change s.charset_connection to ", c.charset_connection) 68 | end 69 | end 70 | 71 | write_log(level.DEBUG, "LEAVE MODIFY_CHARSET") 72 | end 73 | -------------------------------------------------------------------------------- /lib/proxy/crc32.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2011, Qihoo 360 - Chancey 2 | -- this is a slightly modified version used inside the interkomm project 3 | 4 | require("crc32.string") 5 | 6 | module('proxy.crc32', package.seeall) 7 | 8 | function hash(string) 9 | return crc32.crc32(string) 10 | end 11 | -------------------------------------------------------------------------------- /lib/proxy/filter.lua: -------------------------------------------------------------------------------- 1 | module("proxy.filter", package.seeall) 2 | 3 | local config_file = string.format("proxy.conf.config_%s", proxy.global.config.instance) 4 | local config = require(config_file) 5 | local whitelist = config.whitelist 6 | local blacklist = config.blacklist 7 | 8 | local log = require("proxy.log") 9 | local level = log.level 10 | local write_log = log.write_log 11 | 12 | function is_whitelist(tokens) 13 | write_log(level.DEBUG, "ENTER IS_WHITELIST") 14 | local re = false 15 | 16 | local first_token 17 | if tokens[1].token_name ~= "TK_COMMENT" then 18 | first_token = tokens[1].text:upper() 19 | else 20 | first_token = tokens[2].text:upper() 21 | end 22 | 23 | for i = 1, #whitelist do 24 | local wtokens = whitelist[i] 25 | for j = 1, #wtokens do 26 | if first_token == wtokens[j] then 27 | write_log(level.DEBUG, "LEAVE IS_WHITELIST") 28 | return i 29 | end 30 | end 31 | end 32 | 33 | write_log(level.DEBUG, "LEAVE IS_WHITELIST") 34 | return re 35 | end 36 | 37 | function is_blacklist(tokens) 38 | write_log(level.DEBUG, "ENTER IS_BLACKLIST") 39 | local re = false 40 | 41 | local first_token = tokens[1].text:upper() 42 | for i = 1, #blacklist do 43 | local b = blacklist[i] 44 | local first = b.FIRST 45 | local first_not = b.FIRST_NOT 46 | 47 | local meet_first = false 48 | local meet_any = true 49 | local meet_all = true 50 | 51 | if first then 52 | if first == first_token then meet_first = true end 53 | elseif first_not and first_not ~= first_token then 54 | meet_first = true 55 | end 56 | 57 | if meet_first then 58 | local any = b.ANY 59 | if any then 60 | meet_any = false 61 | for j = 1, #tokens do 62 | local token = tokens[j].text:upper() 63 | if any == token then 64 | meet_any = true 65 | break 66 | end 67 | end 68 | end 69 | 70 | local all_not = b.ALL_NOT 71 | if all_not then 72 | for j = 1, #tokens do 73 | local token = tokens[j].text:upper() 74 | if all_not == token then 75 | meet_all = false 76 | break 77 | end 78 | end 79 | end 80 | end 81 | 82 | if meet_first and meet_any and meet_all then 83 | re = true 84 | break 85 | end 86 | end 87 | 88 | write_log(level.DEBUG, "LEAVE IS_BLACKLIST") 89 | return re 90 | end 91 | -------------------------------------------------------------------------------- /lib/proxy/log.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/lib/proxy/log.lua -------------------------------------------------------------------------------- /lib/proxy/split.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/lib/proxy/split.lua -------------------------------------------------------------------------------- /lib/proxy/ticker.lua: -------------------------------------------------------------------------------- 1 | require("time.ticker") 2 | 3 | module("proxy.ticker", package.seeall) 4 | 5 | function tick() 6 | return ticker.tick() 7 | end 8 | -------------------------------------------------------------------------------- /lib/proxy/tokenizer.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/lib/proxy/tokenizer.lua -------------------------------------------------------------------------------- /lib/rw-splitting.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/lib/rw-splitting.lua -------------------------------------------------------------------------------- /lib/sql-tokenizer-gen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "sql-tokenizer.h" 7 | 8 | gboolean trav(gpointer _a, gpointer _b, gpointer _udata) { 9 | gboolean *is_first = _udata; 10 | const char *key = _a; 11 | gint value = GPOINTER_TO_INT(_b); 12 | 13 | if (!*is_first) { 14 | printf(","); 15 | } 16 | printf("\n\t%d /* %s */", value, key); 17 | 18 | *is_first = FALSE; 19 | return FALSE; 20 | } 21 | 22 | int main() { 23 | GTree *tokens; 24 | gboolean is_first = TRUE; 25 | gint i; 26 | 27 | tokens = g_tree_new((GCompareFunc)g_ascii_strcasecmp); 28 | 29 | for (i = 0; i < sql_token_get_last_id(); i++) { 30 | /** only tokens with TK_SQL_* are keyworks */ 31 | if (0 != strncmp(sql_token_get_name(i, NULL), "TK_SQL_", sizeof("TK_SQL_") - 1)) continue; 32 | 33 | g_tree_insert(tokens, (sql_token_get_name(i, NULL) + sizeof("TK_SQL_") - 1), GINT_TO_POINTER(i)); 34 | } 35 | 36 | /* traverse the tree and output all keywords in a sorted way */ 37 | printf("static int sql_keywords[] = {"); 38 | g_tree_foreach(tokens, trav, &is_first); 39 | printf("\n};\n"); 40 | 41 | printf("int *sql_keywords_get() { return sql_keywords; }\n"); 42 | printf("int sql_keywords_get_count() { return sizeof(sql_keywords) / sizeof(sql_keywords[0]); }\n"); 43 | 44 | g_tree_destroy(tokens); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /lib/sql-tokenizer-keywords.h: -------------------------------------------------------------------------------- 1 | #ifndef __SQL_TOKENIZER_KEYWORDS_H__ 2 | #define __SQL_TOKENIZER_KEYWORDS_H__ 3 | 4 | int *sql_keywords_get(void); 5 | int sql_keywords_get_count(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /lib/time-ticker-lua.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "lua-env.h" 4 | 5 | int proxy_tick(lua_State *L) 6 | { 7 | struct timeval tp; 8 | gettimeofday(&tp, 0); 9 | lua_pushnumber(L, tp.tv_sec); 10 | lua_pushnumber(L, tp.tv_usec); 11 | return 2; 12 | } 13 | 14 | static const struct luaL_reg time_ticklib[] = 15 | { 16 | {"tick", proxy_tick}, 17 | {NULL, NULL}, 18 | }; 19 | 20 | extern int luaopen_time_ticker(lua_State *L) 21 | { 22 | luaL_register(L, "ticker", time_ticklib); 23 | return 1; 24 | } 25 | -------------------------------------------------------------------------------- /m4/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST=sed.m4 2 | -------------------------------------------------------------------------------- /mysql-chassis.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: mysql-chassis 7 | Version: @VERSION@ 8 | Description: the Chassis of the MySQL Proxy 9 | URL: http://forge.mysql.com/wiki/MySQL_Proxy 10 | Requires: glib-2.0 >= 2.16, gthread-2.0 >= 2.16 11 | Libs: -L${libdir} -lmysql-chassis 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /mysql-proxy.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | pkglibdir=@libdir@/mysql-proxy 5 | lualibdir=${pkglibdir}/lua 6 | plugindir=${pkglibdir}/plugins 7 | 8 | Name: MySQL Proxy 9 | Version: @VERSION@ 10 | Description: MySQL Proxy 11 | URL: http://forge.mysql.com/wiki/MySQL_Proxy 12 | Requires: glib-2.0 >= 2.16, mysql-chassis >= @VERSION@ 13 | Libs: -L${libdir} -lmysql-proxy 14 | -------------------------------------------------------------------------------- /mysql-proxy.spec.in: -------------------------------------------------------------------------------- 1 | # 2 | # Simple RPM spec file for mysql-proxy 3 | # written by Lenz Grimmer 4 | # 5 | %define prefix /usr 6 | 7 | Summary: A Proxy for the MySQL Client/Server protocol 8 | Name: mysql-proxy 9 | Version: @VERSION@ 10 | Release: 0 11 | License: GPL 12 | Group: Applications/Networking 13 | Source: %{name}-%{version}.tar.gz 14 | URL: http://forge.mysql.com/wiki/MySQL_Proxy 15 | Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root 16 | BuildRequires: mysql-devel glib2-devel libevent 17 | %if 0%{?suse_version} > 1010 18 | %define with_lua 1 19 | %endif 20 | %if 0%{?with_lua} 21 | BuildRequires: lua-devel >= 5.1 22 | %endif 23 | 24 | %description 25 | MySQL Proxy is a simple program that sits between your client and MySQL 26 | server(s) that can monitor, analyze or transform their communication. Its 27 | flexibility allows for unlimited uses; common ones include: load balancing; 28 | failover; query analysis; query filtering and modification; and many more. 29 | 30 | %prep 31 | %setup 32 | 33 | %build 34 | %configure \ 35 | %if 0%{?with_lua} 36 | --with-lua 37 | %else 38 | --without-lua 39 | %endif 40 | %{__make} 41 | 42 | %install 43 | %makeinstall 44 | # we package them later in the documentation. no reason to have them here 45 | %{__rm} -v %{buildroot}%{_datadir}/*.lua 46 | # we dont need to package the Makefile stuff 47 | %{__rm} -v examples/Makefile* 48 | 49 | %clean 50 | %{__rm} -rfv %{buildroot} 51 | 52 | %files 53 | %defattr(-,root,root) 54 | %doc AUTHORS COPYING INSTALL NEWS README README.TESTS 55 | %doc examples/ 56 | %{_bindir}/%{name} 57 | %{_datadir}/%{name}/ 58 | -------------------------------------------------------------------------------- /plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF(WIN32) 2 | ## make sure we only use the smallest set of 3 | ## headers on win32. Otherwise we get clashes 4 | ## between winsock2.h and winsock.h 5 | ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN) 6 | ENDIF(WIN32) 7 | ADD_SUBDIRECTORY(debug) 8 | ADD_SUBDIRECTORY(proxy) 9 | ADD_SUBDIRECTORY(admin) 10 | ADD_SUBDIRECTORY(replicant) 11 | ## needs readline 12 | # ADD_SUBDIRECTORY(cli) 13 | -------------------------------------------------------------------------------- /plugins/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=\ 2 | admin \ 3 | proxy \ 4 | replicant \ 5 | debug 6 | # the cli plugin needs readline and we don't have it on all platforms 7 | # cli 8 | 9 | EXTRA_DIST=CMakeLists.txt 10 | 11 | check-local: 12 | mkdir -p $(top_builddir)/plugins/; 13 | for plugin in $(SUBDIRS); do \ 14 | for i in `cat $(top_builddir)/plugins/$$plugin/.libs/lib$$plugin.la | grep '^dlname' | sed "s/.*=//;s/'//g"`; do \ 15 | echo $$i; \ 16 | ln -fs $(top_builddir)/plugins/$$plugin/.libs/$$i $(top_builddir)/plugins/$$i; \ 17 | done; \ 18 | done; 19 | 20 | clean-local: 21 | ## remove left-overs from the check-local hack in the plugings 22 | -------------------------------------------------------------------------------- /plugins/admin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) 2 | INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) # for config.h 3 | 4 | INCLUDE_DIRECTORIES(${GLIB_INCLUDE_DIRS}) 5 | INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIRS}) 6 | INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIRS}) 7 | INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIRS}) 8 | 9 | LINK_DIRECTORIES(${LUA_LIBRARY_DIRS}) 10 | LINK_DIRECTORIES(${GLIB_LIBRARY_DIRS}) 11 | 12 | SET(_plugin_name admin) 13 | ADD_LIBRARY(${_plugin_name} SHARED "${_plugin_name}-plugin.c") 14 | TARGET_LINK_LIBRARIES(${_plugin_name} mysql-chassis-proxy) 15 | CHASSIS_PLUGIN_INSTALL(${_plugin_name}) 16 | 17 | -------------------------------------------------------------------------------- /plugins/admin/Makefile.am: -------------------------------------------------------------------------------- 1 | plugindir = ${pkglibdir}/plugins 2 | 3 | plugin_LTLIBRARIES = libadmin.la 4 | libadmin_la_LDFLAGS = -export-dynamic -no-undefined -avoid-version -dynamic 5 | libadmin_la_SOURCES = admin-plugin.c 6 | libadmin_la_LIBADD = $(EVENT_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) $(top_builddir)/src/libmysql-proxy.la 7 | libadmin_la_CPPFLAGS = $(MYSQL_CFLAGS) $(GLIB_CFLAGS) $(LUA_CFLAGS) $(GMODULE_CFLAGS) -I$(top_srcdir)/src/ 8 | 9 | EXTRA_DIST=CMakeLists.txt 10 | 11 | -------------------------------------------------------------------------------- /plugins/debug/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) 2 | INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) # for config.h 3 | 4 | INCLUDE_DIRECTORIES(${GLIB_INCLUDE_DIRS}) 5 | INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIRS}) 6 | INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIRS}) 7 | INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIRS}) 8 | 9 | LINK_DIRECTORIES(${LUA_LIBRARY_DIRS}) 10 | LINK_DIRECTORIES(${GLIB_LIBRARY_DIRS}) 11 | 12 | SET(_plugin_name debug) 13 | ADD_LIBRARY(${_plugin_name} SHARED "${_plugin_name}-plugin.c") 14 | TARGET_LINK_LIBRARIES(${_plugin_name} mysql-chassis-proxy) 15 | CHASSIS_PLUGIN_INSTALL(${_plugin_name}) 16 | 17 | -------------------------------------------------------------------------------- /plugins/debug/Makefile.am: -------------------------------------------------------------------------------- 1 | plugindir = ${pkglibdir}/plugins 2 | 3 | plugin_LTLIBRARIES = libdebug.la 4 | libdebug_la_LDFLAGS = -export-dynamic -no-undefined -avoid-version -dynamic 5 | libdebug_la_SOURCES = debug-plugin.c 6 | libdebug_la_LIBADD = $(EVENT_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) $(top_builddir)/src/libmysql-proxy.la 7 | libdebug_la_CPPFLAGS = $(MYSQL_CFLAGS) $(GLIB_CFLAGS) $(LUA_CFLAGS) $(GMODULE_CFLAGS) -I$(top_srcdir)/src/ 8 | 9 | EXTRA_DIST=CMakeLists.txt 10 | 11 | -------------------------------------------------------------------------------- /plugins/proxy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) 2 | INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) # for config.h 3 | 4 | INCLUDE_DIRECTORIES(${GLIB_INCLUDE_DIRS}) 5 | INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIRS}) 6 | INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIRS}) 7 | INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIRS}) 8 | 9 | LINK_DIRECTORIES(${LUA_LIBRARY_DIRS}) 10 | LINK_DIRECTORIES(${GLIB_LIBRARY_DIRS}) 11 | 12 | SET(_plugin_name proxy) 13 | ADD_LIBRARY(${_plugin_name} SHARED "${_plugin_name}-plugin.c") 14 | TARGET_LINK_LIBRARIES(${_plugin_name} mysql-chassis-proxy) 15 | CHASSIS_PLUGIN_INSTALL(${_plugin_name}) 16 | 17 | -------------------------------------------------------------------------------- /plugins/proxy/Makefile.am: -------------------------------------------------------------------------------- 1 | plugindir = ${pkglibdir}/plugins 2 | 3 | plugin_LTLIBRARIES = libproxy.la 4 | libproxy_la_LDFLAGS = -export-dynamic -no-undefined -avoid-version -dynamic 5 | libproxy_la_SOURCES = proxy-plugin.c 6 | libproxy_la_LIBADD = $(EVENT_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) $(top_builddir)/src/libmysql-proxy.la 7 | libproxy_la_CPPFLAGS = $(MYSQL_CFLAGS) $(GLIB_CFLAGS) $(LUA_CFLAGS) $(GMODULE_CFLAGS) -I$(top_srcdir)/src/ 8 | noinst_HEADERS = proxy-plugin.h 9 | 10 | EXTRA_DIST=CMakeLists.txt 11 | 12 | -------------------------------------------------------------------------------- /plugins/proxy/proxy-plugin.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/plugins/proxy/proxy-plugin.c -------------------------------------------------------------------------------- /plugins/proxy/proxy-plugin.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _PROXY_PLUGIN_H 23 | #define _PROXY_PLUGIN_H 24 | 25 | 26 | #endif /* _PROXY_PLUGIN_H */ 27 | 28 | -------------------------------------------------------------------------------- /plugins/replicant/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) 2 | INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) # for config.h 3 | 4 | INCLUDE_DIRECTORIES(${GLIB_INCLUDE_DIRS}) 5 | INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIRS}) 6 | INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIRS}) 7 | INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIRS}) 8 | 9 | LINK_DIRECTORIES(${LUA_LIBRARY_DIRS}) 10 | LINK_DIRECTORIES(${GLIB_LIBRARY_DIRS}) 11 | 12 | SET(_plugin_name replicant) 13 | ADD_LIBRARY(${_plugin_name} SHARED "${_plugin_name}-plugin.c") 14 | TARGET_LINK_LIBRARIES(${_plugin_name} mysql-chassis-proxy) 15 | CHASSIS_PLUGIN_INSTALL(${_plugin_name}) 16 | 17 | -------------------------------------------------------------------------------- /plugins/replicant/Makefile.am: -------------------------------------------------------------------------------- 1 | plugindir = ${pkglibdir}/plugins 2 | 3 | plugin_LTLIBRARIES = libreplicant.la 4 | libreplicant_la_LDFLAGS = -export-dynamic -no-undefined -avoid-version -dynamic 5 | libreplicant_la_SOURCES = replicant-plugin.c 6 | libreplicant_la_LIBADD = $(EVENT_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) $(top_builddir)/src/libmysql-proxy.la 7 | libreplicant_la_CPPFLAGS = $(MYSQL_CFLAGS) $(GLIB_CFLAGS) $(LUA_CFLAGS) $(GMODULE_CFLAGS) -I$(top_srcdir)/src/ 8 | 9 | EXTRA_DIST=CMakeLists.txt 10 | 11 | -------------------------------------------------------------------------------- /script/Makefile: -------------------------------------------------------------------------------- 1 | encrypt:encrypt.o 2 | gcc -o encrypt encrypt.o -lcrypto 3 | 4 | encrypt.o:encrypt.c 5 | gcc -c encrypt.c 6 | 7 | clean: 8 | rm -f encrypt encrypt.o 9 | -------------------------------------------------------------------------------- /script/create_table.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/script/create_table.sh -------------------------------------------------------------------------------- /script/cron.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | process=`ps aux|grep "mysql-proxy --defaults-file=/etc/mysql-proxy.cnf"|grep -v grep|wc -l` 4 | if [ "$process" != "2" ]; then 5 | dir="/usr/local/mysql-proxy/log/" 6 | mkdir -p $dir 7 | file=$dir"error.log" 8 | date=`date` 9 | sh -c "echo $date >> $file" 10 | sh -c "echo 'error: MySQL-Proxy is NOT running' >> $file" 11 | 12 | if [ "$process" == "1" ]; then 13 | killall mysql-proxy 2>/dev/null 14 | rm -f /usr/local/mysql-proxy/bin/pid 15 | if [ "$?" != "0" ]; then 16 | sh -c "echo 'error: failed to stop MySQL-Proxy' >> $file" 17 | exit 2 18 | fi 19 | sleep 2 20 | fi 21 | 22 | /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-proxy.cnf 2> /dev/null 23 | if [ "$?" != "0" ]; then 24 | sh -c "echo 'error: failed to start MySQL-Proxy' >> $file" 25 | exit 1 26 | fi 27 | 28 | sh -c "echo 'OK: MySQL-Proxy is started' >> $file" 29 | exit 0 30 | fi 31 | -------------------------------------------------------------------------------- /script/encrypt.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/script/encrypt.c -------------------------------------------------------------------------------- /script/instances: -------------------------------------------------------------------------------- 1 | s3 = 4040, 4041 2 | hao = 4042, 4043 3 | -------------------------------------------------------------------------------- /script/log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | date=`date +%Y%m%d --date="-1 day"` 4 | dir="/usr/local/mysql-proxy/log" 5 | filelist=`ls $dir/*.log` 6 | 7 | for filename in $filelist 8 | do 9 | logfile=`echo $filename | cut -d '.' -f1` 10 | gzip -c "$filename" > "${logfile}_log.$date.gz" 11 | sh -c "cat /dev/null > $filename" 12 | done 13 | -------------------------------------------------------------------------------- /script/mysql-proxyd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | name="MySQL-Proxy of $1" 4 | proxydir=/usr/local/mysql-proxy 5 | binfile="$proxydir/bin/mysql-proxy" 6 | pidfile="$proxydir/log/$1.pid" 7 | confile="$proxydir/conf/$1.cnf" 8 | 9 | function start() 10 | { 11 | ps -ef | grep "mysql-proxy --defaults-file=.*$1.cnf" | grep -v grep >/dev/null 2>&1 12 | 13 | if [ "$?" == "0" ]; then 14 | echo "error: $name is running now" 15 | exit 2 16 | else 17 | $binfile --defaults-file=$confile 18 | 19 | if [ "$?" == "0" ]; then 20 | echo "OK: $name is started" 21 | else 22 | echo "error: failed to start $name" 23 | exit 2 24 | fi 25 | fi 26 | } 27 | 28 | function stop() 29 | { 30 | ps -ef | grep "mysql-proxy --defaults-file=.*$1.cnf" | grep -v grep >/dev/null 2>&1 31 | 32 | if [ "$?" == "0" ]; then 33 | ps -ef | grep "mysql-proxy --defaults-file=.*$1.cnf" | grep -v grep | awk '{print $2}' | xargs kill -9 >/dev/null 2>&1 34 | 35 | if [ "$?" == "0" ]; then 36 | rm -f $pidfile 37 | echo "OK: $name is stopped" 38 | else 39 | echo "error: failed to stop $name" 40 | exit 3 41 | fi 42 | else 43 | echo "error: $name is NOT running" 44 | exit 3 45 | fi 46 | } 47 | 48 | function restart() 49 | { 50 | stop $1 51 | start $1 52 | } 53 | 54 | function status() 55 | { 56 | ps -ef | grep "mysql-proxy --defaults-file=.*$1.cnf" | grep -v grep >/dev/null 2>&1 57 | 58 | if [ "$?" == "0" ]; then 59 | ps -ef | grep "mysql-proxy --defaults-file=.*$1.cnf" | grep -v grep | awk '{print $2}' | while read proxy_pid; do 60 | echo "$name is running ($proxy_pid)" 61 | done 62 | else 63 | echo "$name is NOT running" 64 | fi 65 | } 66 | 67 | case $2 in 68 | "start") 69 | start $1 70 | ;; 71 | 72 | "stop") 73 | stop $1 74 | ;; 75 | 76 | "restart") 77 | restart $1 78 | ;; 79 | 80 | "status") 81 | status $1 82 | ;; 83 | *) 84 | echo "Usage: $0 instance {start|stop|restart|status}" 85 | exit 1 86 | esac 87 | 88 | exit 0 89 | -------------------------------------------------------------------------------- /src/chassis-event-thread.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/src/chassis-event-thread.c -------------------------------------------------------------------------------- /src/chassis-event-thread.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_EVENT_THREAD_H_ 23 | #define _CHASSIS_EVENT_THREAD_H_ 24 | 25 | #include /* GPtrArray */ 26 | 27 | #include "chassis-exports.h" 28 | #include "chassis-mainloop.h" 29 | #include "network-backend.h" 30 | #include "network-mysqld.h" 31 | 32 | CHASSIS_API void chassis_event_add(network_mysqld_con *client_con); 33 | CHASSIS_API void chassis_event_add_self(chassis *chas, struct event *ev, int timeout); 34 | CHASSIS_API void chassis_event_add_local(chassis *chas, struct event *ev); 35 | 36 | /** 37 | * a event-thread 38 | */ 39 | typedef struct { 40 | chassis *chas; 41 | 42 | //int notify_fd; 43 | int notify_receive_fd; 44 | int notify_send_fd; 45 | 46 | struct event notify_fd_event; 47 | 48 | GThread *thr; 49 | 50 | struct event_base *event_base; 51 | 52 | guint index; 53 | 54 | GAsyncQueue *event_queue; 55 | } chassis_event_thread_t; 56 | 57 | CHASSIS_API chassis_event_thread_t *chassis_event_thread_new(); 58 | CHASSIS_API void chassis_event_thread_free(chassis_event_thread_t *thread); 59 | CHASSIS_API void chassis_event_handle(int event_fd, short events, void *user_data); 60 | CHASSIS_API void chassis_event_thread_set_event_base(chassis_event_thread_t *thread, struct event_base *event_base); 61 | CHASSIS_API void *chassis_event_thread_loop(chassis_event_thread_t *thread); 62 | 63 | CHASSIS_API int chassis_event_threads_init_thread(chassis_event_thread_t *thread, chassis *chas); 64 | CHASSIS_API void chassis_event_threads_start(GPtrArray *threads); 65 | 66 | CHASSIS_API network_connection_pool* chassis_event_thread_pool(network_backend_t* backend); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/chassis-exports.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef _CHASSIS_EXPORTS_ 21 | #define _CHASSIS_EXPORTS_ 22 | 23 | #if defined(_WIN32) 24 | 25 | #if defined(mysql_chassis_EXPORTS) 26 | #define CHASSIS_API __declspec(dllexport) 27 | #elif defined(mysql_chassis_STATIC) 28 | #define CHASSIS_API 29 | #else 30 | #define CHASSIS_API extern __declspec(dllimport) 31 | #endif 32 | 33 | #else 34 | 35 | #define CHASSIS_API extern 36 | 37 | #endif 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/chassis-filemode.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #include "chassis-filemode.h" 29 | 30 | int chassis_filemode_check(const gchar *filename) { 31 | return chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, NULL); 32 | } 33 | 34 | /* 35 | * check whether the given filename points to a file the permissions 36 | * of which are 0 for group and other (ie read/writable only by owner). 37 | * return 0 for "OK", -1 of the file cannot be accessed or is the wrong 38 | * type of file, and 1 if permissions are wrong 39 | * 40 | * since Windows has no concept of owner/group/other, this function 41 | * just return 0 for windows 42 | * 43 | * FIXME? this function currently ignores ACLs 44 | */ 45 | int chassis_filemode_check_full(const gchar *filename, int required_filemask, GError **gerr) { 46 | #ifndef _WIN32 47 | struct stat stbuf; 48 | mode_t fmode; 49 | 50 | if (stat(filename, &stbuf) == -1) { 51 | g_set_error(gerr, G_FILE_ERROR, g_file_error_from_errno(errno), 52 | "cannot stat(%s): %s", filename, 53 | g_strerror(errno)); 54 | return -1; 55 | } 56 | 57 | fmode = stbuf.st_mode; 58 | if ((fmode & S_IFMT) != S_IFREG) { 59 | g_set_error(gerr, G_FILE_ERROR, G_FILE_ERROR_INVAL, 60 | "%s isn't a regular file", filename); 61 | return -1; 62 | } 63 | 64 | if ((fmode & required_filemask) != 0) { 65 | g_set_error(gerr, G_FILE_ERROR, G_FILE_ERROR_PERM, 66 | "permissions of %s aren't secure (0660 or stricter required)", filename); 67 | return 1; 68 | } 69 | 70 | #undef MASK 71 | 72 | #endif /* _WIN32 */ 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /src/chassis-filemode.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_PERM_H_ 23 | #define _CHASSIS_PERM_H_ 24 | 25 | #include 26 | #include "chassis-exports.h" 27 | 28 | #ifdef G_OS_WIN32 29 | /* not used on win32 */ 30 | #define CHASSIS_FILEMODE_SECURE_MASK (0) 31 | #else 32 | #include 33 | #define CHASSIS_FILEMODE_SECURE_MASK (S_IROTH|S_IWOTH|S_IXOTH) 34 | #endif 35 | CHASSIS_API int chassis_filemode_check(const gchar *filename) G_GNUC_DEPRECATED; /* use chassis_filemode_check_full instead */ 36 | CHASSIS_API int chassis_filemode_check_full(const gchar *filename, int required_filemask, GError **gerr); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/chassis-gtimeval.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #include 22 | 23 | #include "chassis-gtimeval.h" 24 | 25 | void chassis_gtime_testset_now(GTimeVal *gt, gint64 *delay) 26 | { 27 | GTimeVal now; 28 | gint64 tdiff; 29 | 30 | if (gt == NULL) 31 | return; 32 | 33 | g_get_current_time(&now); 34 | ge_gtimeval_diff(gt, &now, &tdiff); 35 | 36 | if (tdiff < 0) { 37 | g_critical("%s: time went backwards (%"G_GINT64_FORMAT" usec)!", 38 | G_STRLOC, tdiff); 39 | gt->tv_usec = gt->tv_sec = 0; 40 | goto out; 41 | } 42 | 43 | *gt = now; 44 | out: 45 | if (delay != NULL) 46 | *delay = tdiff; 47 | return; 48 | } 49 | -------------------------------------------------------------------------------- /src/chassis-gtimeval.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #ifndef __CHASSIS_GTIMEVAL_H__ 22 | #define __CHASSIS_GTIMEVAL_H__ 23 | 24 | #include 25 | #include "glib-ext.h" 26 | 27 | /** 28 | * stores the current time in the location passed as argument 29 | * if time is seen to move backwards, output an error message and 30 | * set the time to "0". 31 | * @param pointer to a GTimeVal struct 32 | * @param pointer to a return value, containing difference in usec 33 | * between provided timestamp and "now" 34 | */ 35 | 36 | CHASSIS_API void chassis_gtime_testset_now(GTimeVal *gt, gint64 *delay); 37 | #endif 38 | -------------------------------------------------------------------------------- /src/chassis-keyfile.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_KEYFILE_H_ 23 | #define _CHASSIS_KEYFILE_H_ 24 | 25 | #include 26 | 27 | #include "chassis-exports.h" 28 | 29 | /** @addtogroup chassis */ 30 | /*@{*/ 31 | /** 32 | * parse the configfile options into option entries 33 | * 34 | */ 35 | CHASSIS_API int chassis_keyfile_to_options(GKeyFile *keyfile, const gchar *groupname, GOptionEntry *config_entries); 36 | CHASSIS_API int chassis_keyfile_resolve_path(const char *base_dir, GOptionEntry *config_entries); 37 | 38 | /*@}*/ 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /src/chassis-limits.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include 26 | 27 | #include 28 | #ifdef HAVE_SYS_TIME_H 29 | #include 30 | #endif 31 | #ifdef HAVE_SYS_RESOURCE_H 32 | #include 33 | #endif 34 | #ifdef _WIN32 35 | #include /* for _getmaxstdio() */ 36 | #endif 37 | #include 38 | 39 | #include "chassis-limits.h" 40 | 41 | gint64 chassis_fdlimit_get() { 42 | #ifdef _WIN32 43 | return _getmaxstdio(); 44 | #else 45 | struct rlimit max_files_rlimit; 46 | 47 | if (-1 == getrlimit(RLIMIT_NOFILE, &max_files_rlimit)) { 48 | return -1; 49 | } else { 50 | return max_files_rlimit.rlim_cur; 51 | } 52 | #endif 53 | 54 | } 55 | 56 | /** 57 | * redirect the old call 58 | */ 59 | int chassis_set_fdlimit(int max_files_number) { 60 | return chassis_fdlimit_set(max_files_number); 61 | } 62 | 63 | /** 64 | * set the upper limit of open files 65 | * 66 | * @return -1 on error, 0 on success 67 | */ 68 | int chassis_fdlimit_set(gint64 max_files_number) { 69 | #ifdef _WIN32 70 | int max_files_number_set; 71 | 72 | max_files_number_set = _setmaxstdio(max_files_number); 73 | 74 | if (-1 == max_files_number_set) { 75 | return -1; 76 | } else if (max_files_number_set != max_files_number) { 77 | g_critical("%s: failed to increase the maximum number of open files for stdio: %s (%d)", G_STRLOC, g_strerror(errno), errno); 78 | return -1; 79 | } 80 | 81 | return 0; 82 | #else 83 | struct rlimit max_files_rlimit; 84 | rlim_t soft_limit; 85 | rlim_t hard_limit; 86 | 87 | if (-1 == getrlimit(RLIMIT_NOFILE, &max_files_rlimit)) { 88 | return -1; 89 | } 90 | 91 | soft_limit = max_files_rlimit.rlim_cur; 92 | hard_limit = max_files_rlimit.rlim_max; 93 | 94 | max_files_rlimit.rlim_cur = max_files_number; 95 | if (hard_limit < max_files_number) { /* raise the hard-limit too in case it is smaller than the soft-limit, otherwise we get a EINVAL */ 96 | max_files_rlimit.rlim_max = max_files_number; 97 | } 98 | 99 | if (-1 == setrlimit(RLIMIT_NOFILE, &max_files_rlimit)) { 100 | return -1; 101 | } 102 | 103 | return 0; 104 | #endif 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/chassis-limits.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_LIMITS_H_ 23 | #define _CHASSIS_LIMITS_H_ 24 | 25 | #include /* GPtrArray */ 26 | 27 | #ifdef HAVE_CONFIG_H 28 | #include "config.h" 29 | #endif 30 | 31 | #include "chassis-exports.h" 32 | 33 | CHASSIS_API int chassis_set_fdlimit(int max_files_number) G_GNUC_DEPRECATED; /* use chassis_fdlimit_set() instead */ 34 | 35 | CHASSIS_API int chassis_fdlimit_set(gint64 max_files_number); 36 | CHASSIS_API gint64 chassis_fdlimit_get(void); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/chassis-log.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_LOG_H_ 23 | #define _CHASSIS_LOG_H_ 24 | 25 | #include 26 | #ifdef _WIN32 27 | #include 28 | #endif 29 | 30 | #include "chassis-exports.h" 31 | 32 | #define CHASSIS_RESOLUTION_SEC 0x0 33 | #define CHASSIS_RESOLUTION_MS 0x1 34 | 35 | #define CHASSIS_RESOLUTION_DEFAULT CHASSIS_RESOLUTION_SEC 36 | 37 | /** @addtogroup chassis */ 38 | /*@{*/ 39 | typedef struct { 40 | GLogLevelFlags min_lvl; 41 | 42 | gchar *log_filename; 43 | gint log_file_fd; 44 | 45 | gboolean use_syslog; 46 | 47 | #ifdef _WIN32 48 | HANDLE event_source_handle; 49 | gboolean use_windows_applog; 50 | #endif 51 | gboolean rotate_logs; 52 | 53 | GString *log_ts_str; 54 | gint log_ts_resolution; /*<< timestamp resolution (sec, ms) */ 55 | 56 | GString *last_msg; 57 | time_t last_msg_ts; 58 | guint last_msg_count; 59 | } chassis_log; 60 | 61 | 62 | CHASSIS_API chassis_log *chassis_log_init(void) G_GNUC_DEPRECATED; 63 | CHASSIS_API chassis_log *chassis_log_new(void); 64 | CHASSIS_API int chassis_log_set_level(chassis_log *log, const gchar *level); 65 | CHASSIS_API void chassis_log_free(chassis_log *log); 66 | CHASSIS_API int chassis_log_open(chassis_log *log); 67 | CHASSIS_API void chassis_log_func(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data); 68 | CHASSIS_API void chassis_log_set_logrotate(chassis_log *log); 69 | CHASSIS_API int chassis_log_set_event_log(chassis_log *log, const char *app_name); 70 | CHASSIS_API const char *chassis_log_skip_topsrcdir(const char *message); 71 | CHASSIS_API void chassis_set_logtimestamp_resolution(chassis_log *log, int res); 72 | CHASSIS_API int chassis_get_logtimestamp_resolution(chassis_log *log); 73 | /*@}*/ 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/chassis-mainloop.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_MAINLOOP_H_ 23 | #define _CHASSIS_MAINLOOP_H_ 24 | 25 | #include /* GPtrArray */ 26 | 27 | #ifdef HAVE_CONFIG_H 28 | #include "config.h" 29 | #endif 30 | 31 | #ifdef HAVE_SYS_TIME_H 32 | #include /* event.h needs struct tm */ 33 | #endif 34 | #ifdef HAVE_SYS_TYPES_H 35 | #include 36 | #endif 37 | #ifdef _WIN32 38 | #include 39 | #endif 40 | #include /* struct event_base */ 41 | 42 | #include "chassis-exports.h" 43 | #include "chassis-log.h" 44 | #include "chassis-stats.h" 45 | #include "chassis-shutdown-hooks.h" 46 | #include "lua-scope.h" 47 | #include "network-backend.h" 48 | 49 | /** @defgroup chassis Chassis 50 | * 51 | * the chassis contains the set of functions that are used by all programs 52 | * 53 | * */ 54 | /*@{*/ 55 | typedef struct chassis chassis; 56 | 57 | struct chassis { 58 | struct event_base *event_base; 59 | gchar *event_hdr_version; 60 | 61 | GPtrArray *modules; /**< array(chassis_plugin) */ 62 | 63 | gchar *base_dir; /**< base directory for all relative paths referenced */ 64 | gchar *log_path; /**< log directory */ 65 | gchar *user; /**< user to run as */ 66 | gchar *instance_name; /**< instance name*/ 67 | 68 | chassis_log *log; 69 | 70 | chassis_stats_t *stats; /**< the overall chassis stats, includes lua and glib allocation stats */ 71 | 72 | gint max_conn_for_a_backend; 73 | 74 | /* network-io threads */ 75 | guint event_thread_count; 76 | 77 | GPtrArray *threads; 78 | 79 | chassis_shutdown_hooks_t *shutdown_hooks; 80 | 81 | lua_scope *sc; 82 | 83 | network_backends_t *backends; 84 | 85 | gint wait_timeout; 86 | }; 87 | 88 | CHASSIS_API chassis *chassis_new(void); 89 | CHASSIS_API void chassis_free(chassis *chas); 90 | CHASSIS_API int chassis_check_version(const char *lib_version, const char *hdr_version); 91 | 92 | /** 93 | * the mainloop for all chassis apps 94 | * 95 | * can be called directly or as gthread_* functions 96 | */ 97 | CHASSIS_API int chassis_mainloop(void *user_data); 98 | 99 | CHASSIS_API void chassis_set_shutdown_location(const gchar* location); 100 | CHASSIS_API gboolean chassis_is_shutdown(void); 101 | 102 | #define chassis_set_shutdown() chassis_set_shutdown_location(G_STRLOC) 103 | 104 | /*@}*/ 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/chassis-options.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #ifndef __CHASSIS_OPTIONS_H__ 22 | #define __CHASSIS_OPTIONS_H__ 23 | 24 | #include 25 | 26 | #include "chassis-exports.h" 27 | 28 | /** 29 | * @file 30 | * 31 | * a _new()/_free()-able version of GOptionEntry 32 | */ 33 | 34 | /** 35 | * 'const'-free version of GOptionEntry 36 | */ 37 | typedef struct { 38 | char *long_name; 39 | gchar short_name; 40 | gint flags; 41 | GOptionArg arg; 42 | gpointer arg_data; 43 | char *description; 44 | char *arg_description; 45 | } chassis_option_t; 46 | 47 | /** 48 | * create a chassis_option_t 49 | */ 50 | CHASSIS_API chassis_option_t *chassis_option_new(void); 51 | CHASSIS_API void chassis_option_free(chassis_option_t *opt); 52 | CHASSIS_API int chassis_option_set(chassis_option_t *opt, 53 | const char *long_name, 54 | gchar short_name, 55 | gint flags, 56 | GOptionArg arg, 57 | gpointer arg_data, 58 | const char *description, 59 | const char *arg_description); 60 | 61 | typedef struct { 62 | GList *options; /* List of chassis_option_t */ 63 | GOptionContext *ctx; 64 | } chassis_options_t; 65 | 66 | CHASSIS_API chassis_options_t *chassis_options_new(void); 67 | CHASSIS_API void chassis_options_free(chassis_options_t *opts); 68 | CHASSIS_API int chassis_options_add_option(chassis_options_t *opts, chassis_option_t *opt); 69 | CHASSIS_API int chassis_options_add(chassis_options_t *opts, 70 | const char *long_name, 71 | gchar short_name, 72 | gint flags, 73 | GOptionArg arg, 74 | gpointer arg_data, 75 | const char *description, 76 | const char *arg_description); 77 | 78 | CHASSIS_API GOptionEntry *chassis_options_to_g_option_entries(chassis_options_t *opts); 79 | CHASSIS_API void chassis_options_free_g_option_entries(chassis_options_t G_GNUC_UNUSED *opts, GOptionEntry *entries); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/chassis-path.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #include 22 | 23 | #include 24 | #ifdef WIN32 25 | /* need something compatible, taken from MSDN docs */ 26 | #define PATH_MAX MAX_PATH 27 | #include 28 | #else 29 | #include /* for realpath */ 30 | #endif 31 | #include "chassis-path.h" 32 | 33 | gchar *chassis_get_basedir(const gchar *prgname) { 34 | gchar *absolute_path; 35 | gchar *bin_dir; 36 | gchar r_path[PATH_MAX]; 37 | gchar *base_dir; 38 | 39 | if (g_path_is_absolute(prgname)) { 40 | absolute_path = g_strdup(prgname); /* No need to dup, just to get free right */ 41 | } else { 42 | /** 43 | * the path wasn't absolute 44 | * 45 | * Either it is 46 | * - in the $PATH 47 | * - relative like ./bin/... or 48 | */ 49 | 50 | absolute_path = g_find_program_in_path(prgname); 51 | if (absolute_path == NULL) { 52 | g_critical("can't find myself (%s) in PATH", prgname); 53 | 54 | return NULL; 55 | } 56 | 57 | if (!g_path_is_absolute(absolute_path)) { 58 | gchar *cwd = g_get_current_dir(); 59 | 60 | g_free(absolute_path); 61 | 62 | absolute_path = g_build_filename(cwd, prgname, NULL); 63 | 64 | g_free(cwd); 65 | } 66 | } 67 | 68 | /* assume that the binary is in ./s?bin/ and that the the basedir is right above it 69 | * 70 | * to get this working we need a "clean" basedir, no .../foo/./bin/ 71 | */ 72 | #ifdef WIN32 73 | if (0 == GetFullPathNameA(absolute_path, PATH_MAX, r_path, NULL)) { 74 | g_critical("%s: GetFullPathNameA(%s) failed: %s", 75 | G_STRLOC, 76 | absolute_path, 77 | g_strerror(errno)); 78 | 79 | return NULL; 80 | } 81 | #else 82 | if (NULL == realpath(absolute_path, r_path)) { 83 | g_critical("%s: realpath(%s) failed: %s", 84 | G_STRLOC, 85 | absolute_path, 86 | g_strerror(errno)); 87 | 88 | return NULL; 89 | } 90 | #endif 91 | bin_dir = g_path_get_dirname(r_path); 92 | base_dir = g_path_get_dirname(bin_dir); 93 | 94 | /* don't free base_dir, because we need it later */ 95 | g_free(absolute_path); 96 | g_free(bin_dir); 97 | 98 | return base_dir; 99 | } 100 | 101 | /** 102 | * Helper function to correctly take into account the users base-dir setting for 103 | * paths that might be relative. 104 | * Note: Because this function potentially frees the pointer to gchar* that's passed in and cannot lock 105 | * on that, it is _not_ threadsafe. You have to ensure threadsafety yourself! 106 | * @returns TRUE if it modified the filename, FALSE if it didn't 107 | */ 108 | gboolean chassis_resolve_path(const char *base_dir, gchar **filename) { 109 | gchar *new_path = NULL; 110 | 111 | if (!base_dir || 112 | !filename || 113 | !*filename) 114 | return FALSE; 115 | 116 | /* don't even look at absolute paths */ 117 | if (g_path_is_absolute(*filename)) return FALSE; 118 | 119 | new_path = g_build_filename(base_dir, G_DIR_SEPARATOR_S, *filename, NULL); 120 | 121 | g_debug("%s.%d: adjusting relative path (%s) to base_dir (%s). New path: %s", __FILE__, __LINE__, *filename, base_dir, new_path); 122 | 123 | g_free(*filename); 124 | *filename = new_path; 125 | return TRUE; 126 | } 127 | 128 | 129 | -------------------------------------------------------------------------------- /src/chassis-path.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #ifndef __CHASSIS_PATH_H__ 22 | #define __CHASSIS_PATH_H__ 23 | 24 | #include 25 | 26 | #include "chassis-exports.h" 27 | 28 | CHASSIS_API gboolean chassis_resolve_path(const char *base_dir, gchar **filename); 29 | CHASSIS_API gchar *chassis_get_basedir(const gchar *prgname); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/chassis-plugin.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_PLUGIN_H_ 23 | #define _CHASSIS_PLUGIN_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include "chassis-mainloop.h" 29 | #include "chassis-exports.h" 30 | 31 | /* current magic is 0.8.0-1 */ 32 | #define CHASSIS_PLUGIN_MAGIC 0x00080001L 33 | 34 | /** 35 | * The private stats structure of a plugin. This is opaque to the rest of the code, 36 | * we can only get a copy of it in a hash. 37 | * @see chassis_plugin_stats.get_stats() 38 | */ 39 | typedef struct chassis_plugin_stats chassis_plugin_stats_t; 40 | typedef struct chassis_plugin_config chassis_plugin_config; 41 | 42 | typedef struct chassis_plugin { 43 | long magic; /**< a magic token to verify that the plugin API matches */ 44 | 45 | gchar *option_grp_name; /**< name of the option group (used in --help- */ 46 | gchar *name; /**< user visible name of this plugin */ 47 | gchar *version; /**< the plugin's version number */ 48 | GModule *module; /**< the plugin handle when loaded */ 49 | 50 | chassis_plugin_stats_t *stats; /**< contains the plugin-specific statistics */ 51 | 52 | chassis_plugin_stats_t *(*new_stats)(void); /**< handler function to initialize the plugin-specific stats */ 53 | void (*free_stats)(chassis_plugin_stats_t *user_data); /**< handler function to dealloc the plugin-specific stats */ 54 | GHashTable *(*get_stats)(chassis_plugin_stats_t *user_data); /**< handler function to retrieve the plugin-specific stats */ 55 | 56 | chassis_plugin_config *config; /**< contains the plugin-specific config data */ 57 | 58 | chassis_plugin_config *(*init)(void); /**< handler function to allocate/initialize a chassis_plugin_config struct */ 59 | void (*destroy)(chassis_plugin_config *user_data); /**< handler function used to deallocate the chassis_plugin_config */ 60 | GOptionEntry * (*get_options)(chassis_plugin_config *user_data); /**< handler function to obtain the command line argument information */ 61 | int (*apply_config)(chassis *chas, chassis_plugin_config * user_data); /**< handler function to set the argument values in the plugin's config */ 62 | void* (*get_global_state)(chassis_plugin_config *user_data, const char* member); /**< handler function to retrieve the plugin's global state */ 63 | 64 | } chassis_plugin; 65 | 66 | CHASSIS_API chassis_plugin *chassis_plugin_init(void) G_GNUC_DEPRECATED; 67 | CHASSIS_API chassis_plugin *chassis_plugin_new(void); 68 | CHASSIS_API chassis_plugin *chassis_plugin_load(const gchar *name); 69 | CHASSIS_API void chassis_plugin_free(chassis_plugin *p); 70 | CHASSIS_API GOptionEntry * chassis_plugin_get_options(chassis_plugin *p); 71 | 72 | /** 73 | * Retrieve the chassis plugin for a particular name. 74 | * 75 | * @param chas a pointer to the chassis 76 | * @param plugin_name The name of the plugin to look up. 77 | * @return A pointer to a chassis_plugin structure 78 | * @retval NULL if there is no loaded chassis with this name 79 | */ 80 | CHASSIS_API chassis_plugin* chassis_plugin_for_name(chassis *chas, gchar* plugin_name); 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/chassis-shutdown-hooks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "chassis-shutdown-hooks.h" 5 | #include "glib-ext.h" 6 | 7 | static void g_string_free_true(gpointer data) { 8 | g_string_free(data, TRUE); 9 | } 10 | 11 | 12 | chassis_shutdown_hook_t *chassis_shutdown_hook_new() { 13 | chassis_shutdown_hook_t *hook; 14 | 15 | hook = g_slice_new0(chassis_shutdown_hook_t); 16 | hook->func = NULL; 17 | hook->udata = NULL; 18 | hook->is_called = FALSE; 19 | 20 | return hook; 21 | } 22 | 23 | void chassis_shutdown_hook_free(chassis_shutdown_hook_t *hook) { 24 | g_slice_free(chassis_shutdown_hook_t, hook); 25 | } 26 | 27 | chassis_shutdown_hooks_t *chassis_shutdown_hooks_new() { 28 | chassis_shutdown_hooks_t *hooks; 29 | 30 | hooks = g_slice_new0(chassis_shutdown_hooks_t); 31 | hooks->hooks = g_hash_table_new_full( 32 | (GHashFunc)g_string_hash, 33 | (GEqualFunc)g_string_equal, 34 | g_string_free_true, 35 | (GDestroyNotify)chassis_shutdown_hook_free); 36 | hooks->mutex = g_mutex_new(); 37 | 38 | return hooks; 39 | } 40 | 41 | void chassis_shutdown_hooks_free(chassis_shutdown_hooks_t *hooks) { 42 | g_hash_table_destroy(hooks->hooks); 43 | g_mutex_free(hooks->mutex); 44 | 45 | g_slice_free(chassis_shutdown_hooks_t, hooks); 46 | } 47 | 48 | void chassis_shutdown_hooks_lock(chassis_shutdown_hooks_t *hooks) { 49 | g_mutex_lock(hooks->mutex); 50 | } 51 | 52 | void chassis_shutdown_hooks_unlock(chassis_shutdown_hooks_t *hooks) { 53 | g_mutex_unlock(hooks->mutex); 54 | } 55 | 56 | /** 57 | * register a shutdown hook 58 | * 59 | * @return TRUE if registering succeeded, FALSE if already known 60 | */ 61 | gboolean chassis_shutdown_hooks_register(chassis_shutdown_hooks_t *hooks, 62 | const char *key, gsize key_len, 63 | chassis_shutdown_hook_t *hook) { 64 | gboolean is_inserted = FALSE; 65 | 66 | chassis_shutdown_hooks_lock(hooks); 67 | if (NULL == g_hash_table_lookup_const(hooks->hooks, key, key_len)) { 68 | g_hash_table_insert(hooks->hooks, g_string_new_len(key, key_len), hook); 69 | is_inserted = TRUE; 70 | } 71 | chassis_shutdown_hooks_unlock(hooks); 72 | 73 | return is_inserted; 74 | } 75 | 76 | void chassis_shutdown_hooks_call(chassis_shutdown_hooks_t *hooks) { 77 | GHashTableIter iter; 78 | GString *key; 79 | chassis_shutdown_hook_t *hook; 80 | 81 | chassis_shutdown_hooks_lock(hooks); 82 | g_hash_table_iter_init(&iter, hooks->hooks); 83 | while (g_hash_table_iter_next(&iter, (void **)&key, (void **)&hook)) { 84 | if (hook->func && !hook->is_called) hook->func(hook->udata); 85 | hook->is_called = TRUE; 86 | } 87 | chassis_shutdown_hooks_unlock(hooks); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/chassis-shutdown-hooks.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_SHUTDOWN_HOOKS_H_ 23 | #define _CHASSIS_SHUTDOWN_HOOKS_H_ 24 | 25 | #include /* GPtrArray */ 26 | 27 | #ifdef HAVE_CONFIG_H 28 | #include "config.h" 29 | #endif 30 | 31 | #include "chassis-exports.h" 32 | 33 | typedef struct { 34 | void (*func)(gpointer _udata); 35 | gpointer udata; 36 | gboolean is_called; 37 | } chassis_shutdown_hook_t; 38 | 39 | CHASSIS_API chassis_shutdown_hook_t *chassis_shutdown_hook_new(void); 40 | CHASSIS_API void chassis_shutdown_hook_free(chassis_shutdown_hook_t *); 41 | 42 | typedef struct { 43 | GMutex *mutex; 44 | GHashTable *hooks; 45 | } chassis_shutdown_hooks_t; 46 | 47 | CHASSIS_API chassis_shutdown_hooks_t *chassis_shutdown_hooks_new(void); 48 | CHASSIS_API void chassis_shutdown_hooks_free(chassis_shutdown_hooks_t *); 49 | CHASSIS_API gboolean chassis_shutdown_hooks_register(chassis_shutdown_hooks_t *hooks, 50 | const char *key, gsize key_len, 51 | chassis_shutdown_hook_t *hook); 52 | CHASSIS_API void chassis_shutdown_hooks_call(chassis_shutdown_hooks_t *hooks); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/chassis-stats.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include 27 | #include "chassis-stats.h" 28 | 29 | chassis_stats_t *chassis_global_stats = NULL; 30 | 31 | chassis_stats_t * chassis_stats_new(void) { 32 | if (chassis_global_stats != NULL) return chassis_global_stats; 33 | 34 | chassis_global_stats = g_new0(chassis_stats_t, 1); 35 | g_debug("%s: created new global chassis stats at %p", G_STRLOC, (void*)chassis_global_stats); 36 | 37 | return chassis_global_stats; 38 | } 39 | 40 | void chassis_stats_free(chassis_stats_t *stats) { 41 | if (!stats) return; 42 | 43 | if (stats == chassis_global_stats) { 44 | g_free(stats); 45 | chassis_global_stats = NULL; 46 | } else { 47 | /* there should only be one glbal chassis stats struct at any given time */ 48 | g_assert_not_reached(); 49 | } 50 | } 51 | 52 | GHashTable* chassis_stats_get(chassis_stats_t *stats){ 53 | GHashTable *stats_hash; 54 | 55 | if (stats == NULL) return NULL; 56 | 57 | /* NOTE: the keys are strdup'ed, the values are simply integers */ 58 | stats_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); 59 | 60 | #define STR(x) #x 61 | #define N(x) g_strdup(x) 62 | #define ADD_STAT(x) g_hash_table_insert(stats_hash, N( STR(x)), GUINT_TO_POINTER(g_atomic_int_get(&(stats->x)))) 63 | #define ADD_ALLOC_STAT(x) ADD_STAT(x ## _alloc); ADD_STAT(x ## _free); 64 | 65 | ADD_ALLOC_STAT(lua_mem); 66 | ADD_STAT(lua_mem_bytes); 67 | ADD_STAT(lua_mem_bytes_max); 68 | 69 | #undef N 70 | #undef STR 71 | #undef ADD_STAT 72 | #undef ADD_ALLOC_STAT 73 | 74 | return stats_hash; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/chassis-stats.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_STATS_H_ 23 | #define _CHASSIS_STATS_H_ 24 | 25 | #include 26 | #include "chassis-exports.h" 27 | 28 | typedef struct chassis_stats { 29 | volatile gint lua_mem_alloc; 30 | volatile gint lua_mem_free; 31 | volatile gint lua_mem_bytes; 32 | volatile gint lua_mem_bytes_max; 33 | } chassis_stats_t; 34 | 35 | CHASSIS_API chassis_stats_t *chassis_global_stats; 36 | 37 | CHASSIS_API chassis_stats_t * chassis_stats_new(void); 38 | CHASSIS_API void chassis_stats_free(chassis_stats_t *stats); 39 | 40 | CHASSIS_API GHashTable* chassis_stats_get(chassis_stats_t *user_data); 41 | 42 | #define CHASSIS_STATS_ALLOC_INC_NAME(name) ((chassis_global_stats != NULL) ? g_atomic_int_inc(&(chassis_global_stats->name ## _alloc)) : (void)0) 43 | #define CHASSIS_STATS_FREE_INC_NAME(name) ((chassis_global_stats != NULL) ? g_atomic_int_inc(&(chassis_global_stats->name ## _free)) : (void)0) 44 | #define CHASSIS_STATS_ADD_NAME(name, addme) ((chassis_global_stats != NULL) ? g_atomic_int_add(&(chassis_global_stats->name), addme) : (void)0) 45 | #define CHASSIS_STATS_GET_NAME(name) ((chassis_global_stats != NULL) ? g_atomic_int_get(&(chassis_global_stats->name)) : 0) 46 | #define CHASSIS_STATS_SET_NAME(name, setme) ((chassis_global_stats != NULL) ? g_atomic_int_set(&(chassis_global_stats->name), setme) : (void)0) 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/chassis-unix-daemon.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #ifndef __CHASSIS_UNIX_DAEMON_H__ 22 | #define __CHASSIS_UNIX_DAEMON_H__ 23 | 24 | int chassis_unix_proc_keepalive(int *child_exit_status, const char *pid_file); 25 | void chassis_unix_daemonize(void); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/chassis-win32-service.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #ifndef __CHASSIS_WIN32_SERVICE_H__ 22 | #define __CHASSIS_WIN32_SERVICE_H__ 23 | 24 | #ifdef _WIN32 25 | #include /* for the DWORD */ 26 | #endif 27 | 28 | #include 29 | 30 | #include "chassis-exports.h" 31 | 32 | CHASSIS_API gboolean chassis_win32_is_service(void); 33 | CHASSIS_API int main_win32(int argc, char **argv, int (*main_cmdline)(int , char **)); 34 | #ifdef _WIN32 35 | CHASSIS_API void chassis_win32_service_set_state(DWORD new_state, int wait_msec); 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/disable-dtrace.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | /* short out DTrace macros if we don't have or want DTrace support */ 21 | #ifndef ENABLE_DTRACE 22 | 23 | #define DTRACE_PROBE(provider, name) 24 | #define DTRACE_PROBE1(provider, name, arg0) 25 | #define DTRACE_PROBE2(provider, name, arg0, arg1) 26 | #define DTRACE_PROBE3(provider, name, arg0, arg1, arg2) 27 | #define DTRACE_PROBE4(provider, name, arg0, arg1, arg2, arg3) 28 | #define DTRACE_PROBE5(provider, name, arg0, arg1, arg2, arg3, arg4) 29 | #define DTRACE_PROBE6(provider, name, arg0, arg1, arg2, arg3, arg4, arg5) 30 | #define DTRACE_PROBE7(provider, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6) 31 | #define DTRACE_PROBE8(provider, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) 32 | #define DTRACE_PROBE9(provider, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) 33 | #define DTRACE_PROBE10(provider, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) 34 | 35 | /* when adding new DTrace USDT probes, also add the stubs below */ 36 | 37 | #define MYSQLPROXY_STATE_CHANGE_ENABLED() FALSE 38 | #define MYSQLPROXY_STATE_CHANGE(arg0, arg1, arg2) 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/glib-ext-ref.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #include 22 | #include "glib-ext-ref.h" 23 | 24 | /** 25 | * create a new reference object 26 | * 27 | * @see g_ref_unref 28 | */ 29 | GRef *g_ref_new() { 30 | GRef *ref; 31 | 32 | ref = g_new0(GRef, 1); 33 | ref->ref_count = 0; 34 | ref->udata = NULL; 35 | 36 | return ref; 37 | } 38 | 39 | /** 40 | * set the referenced data and its free-function 41 | * 42 | * increments the ref-counter by one 43 | */ 44 | void g_ref_set(GRef *ref, gpointer udata, GDestroyNotify udata_free) { 45 | g_return_if_fail(ref->ref_count == 0); 46 | 47 | ref->udata = udata; 48 | ref->udata_free = udata_free; 49 | ref->ref_count = 1; 50 | } 51 | 52 | /** 53 | * increment the ref counter 54 | */ 55 | void g_ref_ref(GRef *ref) { 56 | g_return_if_fail(ref->ref_count > 0); 57 | 58 | ref->ref_count++; 59 | } 60 | 61 | /** 62 | * unreference a object 63 | * 64 | * if no other object references this free the object 65 | */ 66 | void g_ref_unref(GRef *ref) { 67 | if (ref->ref_count == 0) { 68 | /* not set yet */ 69 | } else if (--ref->ref_count == 0) { 70 | if (ref->udata_free) { 71 | ref->udata_free(ref->udata); 72 | ref->udata = NULL; 73 | } 74 | g_free(ref); 75 | } 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/glib-ext-ref.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _GLIB_EXT_REF_H_ 23 | #define _GLIB_EXT_REF_H_ 24 | 25 | #include 26 | 27 | #include "chassis-exports.h" 28 | 29 | /** 30 | * a ref-counted c-structure 31 | * 32 | */ 33 | typedef struct { 34 | gpointer udata; 35 | GDestroyNotify udata_free; 36 | 37 | gint ref_count; 38 | } GRef; 39 | 40 | CHASSIS_API GRef *g_ref_new(void); 41 | CHASSIS_API void g_ref_set(GRef *ref, gpointer udata, GDestroyNotify udata_free); 42 | CHASSIS_API void g_ref_ref(GRef *ref); 43 | CHASSIS_API void g_ref_unref(GRef *ref); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/glib-ext.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _GLIB_EXT_H_ 23 | #define _GLIB_EXT_H_ 24 | 25 | #include 26 | 27 | #include "chassis-exports.h" 28 | 29 | CHASSIS_API void g_list_string_free(gpointer data, gpointer user_data); 30 | 31 | CHASSIS_API gboolean g_hash_table_true(gpointer key, gpointer value, gpointer user_data); 32 | CHASSIS_API guint g_hash_table_string_hash(gconstpointer _key); 33 | CHASSIS_API gboolean g_hash_table_string_equal(gconstpointer _a, gconstpointer _b); 34 | CHASSIS_API void g_hash_table_string_free(gpointer data); 35 | CHASSIS_API gpointer g_hash_table_lookup_const(GHashTable *h, const gchar *name, gsize name_len); 36 | CHASSIS_API guint g_istr_hash(gconstpointer v); 37 | 38 | CHASSIS_API GString *g_string_dup(GString *); 39 | 40 | CHASSIS_API gboolean strleq(const gchar *a, gsize a_len, const gchar *b, gsize b_len); 41 | CHASSIS_API gboolean g_string_equal_ci(const GString *a, const GString *b); 42 | CHASSIS_API gboolean g_memeq(const char *a, gsize a_len, const char *b, gsize b_len); 43 | 44 | CHASSIS_API int g_string_get_time(GString *s, GTimeVal *gt); 45 | CHASSIS_API int g_string_get_current_time(GString *s); 46 | CHASSIS_API void ge_gtimeval_diff(GTimeVal *old, GTimeVal *new, gint64 *delay); 47 | CHASSIS_API GString *g_string_assign_len(GString *s, const char *, gsize ); 48 | CHASSIS_API void g_debug_hexdump(const char *msg, const void *s, size_t len); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/lua-env.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifdef HAVE_CONFIG_H 21 | #include "config.h" 22 | #endif 23 | 24 | #include 25 | 26 | #include "lua-env.h" 27 | 28 | /** 29 | * convinience functions for some lua lib/api functions 30 | */ 31 | 32 | /** 33 | * taken from lapi.c 34 | */ 35 | /* convert a stack index to positive */ 36 | #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ 37 | lua_gettop(L) + (i) + 1) 38 | void lua_getfield_literal (lua_State *L, int idx, const char *k, size_t k_len) { 39 | idx = abs_index(L, idx); 40 | 41 | lua_pushlstring(L, k, k_len); 42 | 43 | lua_gettable(L, idx); 44 | } 45 | 46 | /** 47 | * check pass through the userdata as is 48 | */ 49 | void *luaL_checkself (lua_State *L) { 50 | return lua_touserdata(L, 1); 51 | } 52 | 53 | /** 54 | * emulate luaL_newmetatable() with lightuserdata instead of strings 55 | * 56 | * this is a lot faster than doing hashing on strings as we can just 57 | * hash on a fixed memory-address 58 | * 59 | * to make this work, the methods array has to be declared static to 60 | * keep its location 61 | */ 62 | int proxy_getmetatable(lua_State *L, const luaL_reg *methods) { 63 | /* check if the */ 64 | 65 | lua_pushlightuserdata(L, (luaL_reg *)methods); 66 | lua_gettable(L, LUA_REGISTRYINDEX); 67 | 68 | if (lua_isnil(L, -1)) { 69 | /* not found */ 70 | lua_pop(L, 1); 71 | 72 | lua_newtable(L); 73 | luaL_register(L, NULL, methods); 74 | 75 | lua_pushlightuserdata(L, (luaL_reg *)methods); 76 | lua_pushvalue(L, -2); 77 | lua_settable(L, LUA_REGISTRYINDEX); 78 | } 79 | g_assert(lua_istable(L, -1)); 80 | 81 | return 1; 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/lua-env.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef __LUA_ENV_H__ 21 | #define __LUA_ENV_H__ 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "network-exports.h" 30 | 31 | NETWORK_API void lua_getfield_literal (lua_State *L, int idx, const char *k, size_t k_len); 32 | NETWORK_API void *luaL_checkself (lua_State *L); 33 | NETWORK_API int proxy_getmetatable(lua_State *L, const luaL_reg *methods); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/lua-load-factory.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _LUA_LOAD_FACTORY_ 23 | #define _LUA_LOAD_FACTORY_ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | #include "config.h" 27 | #endif 28 | 29 | #ifdef HAVE_LUA_H 30 | #include 31 | 32 | int luaL_loadstring_factory(lua_State *L, const char *s); 33 | int luaL_loadfile_factory(lua_State *L, const char *filename); 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/lua-registry-keys.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _CHASSIS_LUA_REGISTRY_KEYS_H_ 23 | #define _CHASSIS_LUA_REGISTRY_KEYS_H_ 24 | 25 | #define CHASSIS_LUA_REGISTRY_KEY "chassis" 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/lua-scope.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _LUA_SCOPE_H_ 23 | #define _LUA_SCOPE_H_ 24 | 25 | #include 26 | 27 | #ifdef HAVE_CONFIG_H 28 | #include "config.h" 29 | #endif 30 | 31 | #ifdef HAVE_LUA_H 32 | #include 33 | #endif 34 | 35 | #include "chassis-exports.h" 36 | 37 | typedef struct { 38 | #ifdef HAVE_LUA_H 39 | lua_State *L; 40 | int L_ref; 41 | #endif 42 | GMutex *mutex; /*remove lock*/ 43 | 44 | int L_top; 45 | } lua_scope; 46 | 47 | CHASSIS_API lua_scope *lua_scope_init(void) G_GNUC_DEPRECATED; 48 | CHASSIS_API lua_scope *lua_scope_new(void); 49 | CHASSIS_API void lua_scope_free(lua_scope *sc); 50 | 51 | CHASSIS_API void lua_scope_get(lua_scope *sc, const char* pos); 52 | CHASSIS_API void lua_scope_release(lua_scope *sc, const char* pos); 53 | 54 | #define LOCK_LUA(sc) \ 55 | lua_scope_get(sc, G_STRLOC); 56 | 57 | #define UNLOCK_LUA(sc) \ 58 | lua_scope_release(sc, G_STRLOC); 59 | 60 | #ifdef HAVE_LUA_H 61 | CHASSIS_API lua_State *lua_scope_load_script(lua_scope *sc, const gchar *name); 62 | CHASSIS_API void proxy_lua_dumpstack_verbose(lua_State *L); 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/my_timer_cycles.il: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2008 Sun Microsystems, Inc 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 15 | 16 | /* Sun Studio SPARC inline templates for cycle timer */ 17 | /* Sun Studio i386 and x86_64 inline templates for cycle timer */ 18 | /* I didn't say ".volatile" or ".nonvolatile". */ 19 | 20 | .inline my_timer_cycles_il_sparc64,0 21 | rd %tick,%o0 22 | .end 23 | 24 | .inline my_timer_cycles_il_sparc32,0 25 | rd %tick,%o2 26 | srlx %o2,32,%o0 27 | sra %o2,0,%o1 28 | .end 29 | 30 | .inline my_timer_cycles_il_i386,0 31 | rdtsc 32 | .end 33 | 34 | .inline my_timer_cycles_il_x86_64,0 35 | rdtsc 36 | shlq $32,%rdx 37 | orq %rdx,%rax 38 | .end 39 | -------------------------------------------------------------------------------- /src/network-address-lua.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #include "config.h" 22 | #include 23 | 24 | #ifdef WIN32 25 | #include 26 | #include 27 | #else 28 | #include 29 | #endif 30 | 31 | #include "lua-env.h" 32 | #include "glib-ext.h" 33 | 34 | #include "network-address.h" 35 | #include "network-address-lua.h" 36 | 37 | #define C(x) x, sizeof(x) - 1 38 | #define S(x) x->str, x->len 39 | 40 | static int proxy_address_get(lua_State *L) { 41 | network_address *addr = *(network_address **)luaL_checkself(L); 42 | gsize keysize = 0; 43 | const char *key = luaL_checklstring(L, 2, &keysize); 44 | 45 | if (strleq(key, keysize, C("type"))) { 46 | lua_pushinteger(L, addr->addr.common.sa_family); 47 | } else if (strleq(key, keysize, C("name"))) { 48 | lua_pushlstring(L, S(addr->name)); 49 | } else if (strleq(key, keysize, C("address"))) { 50 | #ifdef HAVE_INET_NTOP 51 | char dst_addr[INET6_ADDRSTRLEN]; 52 | #endif 53 | const char *str = NULL; 54 | 55 | switch (addr->addr.common.sa_family) { 56 | case AF_INET: 57 | str = inet_ntoa(addr->addr.ipv4.sin_addr); 58 | if (!str) { 59 | /* it shouldn't really fail, how about logging it ? */ 60 | } 61 | break; 62 | #ifdef HAVE_INET_NTOP 63 | case AF_INET6: 64 | str = inet_ntop(addr->addr.common.sa_family, &addr->addr.ipv6.sin6_addr, dst_addr, sizeof(dst_addr)); 65 | if (!str) { 66 | /* it shouldn't really fail, how about logging it ? */ 67 | } 68 | break; 69 | #endif 70 | #ifndef WIN32 71 | case AF_UNIX: 72 | str = addr->addr.un.sun_path; 73 | break; 74 | #endif 75 | default: 76 | break; 77 | } 78 | 79 | if (NULL == str) { 80 | lua_pushnil(L); 81 | } else { 82 | lua_pushstring(L, str); 83 | } 84 | } else if (strleq(key, keysize, C("port"))) { 85 | switch (addr->addr.common.sa_family) { 86 | case AF_INET: 87 | lua_pushinteger(L, ntohs(addr->addr.ipv4.sin_port)); 88 | break; 89 | case AF_INET6: 90 | lua_pushinteger(L, ntohs(addr->addr.ipv6.sin6_port)); 91 | break; 92 | default: 93 | lua_pushnil(L); 94 | break; 95 | } 96 | } else { 97 | lua_pushnil(L); 98 | } 99 | 100 | return 1; 101 | } 102 | 103 | int network_address_lua_getmetatable(lua_State *L) { 104 | static const struct luaL_reg methods[] = { 105 | { "__index", proxy_address_get }, 106 | { NULL, NULL }, 107 | }; 108 | return proxy_getmetatable(L, methods); 109 | } 110 | 111 | int network_address_lua_push(lua_State *L, network_address *addr) { 112 | network_address **address_p; 113 | 114 | if (!addr) { 115 | lua_pushnil(L); 116 | return 1; 117 | } 118 | 119 | address_p = lua_newuserdata(L, sizeof(network_address)); 120 | *address_p = addr; 121 | 122 | network_address_lua_getmetatable(L); 123 | lua_setmetatable(L, -2); /* tie the metatable to the table (sp -= 1) */ 124 | 125 | return 1; 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/network-address-lua.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef __NETWORK_ADDRESS_LUA_H__ 21 | #define __NETWORK_ADDRESS_LUA_H__ 22 | 23 | #include 24 | 25 | #include "network-exports.h" 26 | 27 | NETWORK_API int network_address_lua_getmetatable(lua_State *L); 28 | NETWORK_API int network_address_lua_push(lua_State *L, network_address *addr); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/network-address.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _NETWORK_ADDRESS_H_ 23 | #define _NETWORK_ADDRESS_H_ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | #include "config.h" 27 | #endif 28 | 29 | #include 30 | 31 | #ifndef _WIN32 32 | #ifdef HAVE_NETINET_IN_H 33 | #include /** struct sockaddr_in */ 34 | #endif 35 | #include 36 | 37 | #ifdef HAVE_SYS_UN_H 38 | #include /** struct sockaddr_un */ 39 | #endif 40 | #include /** struct sockaddr (freebsd and hp/ux need it) */ 41 | #else 42 | #include 43 | #include 44 | #endif 45 | 46 | #include "network-exports.h" 47 | 48 | #ifdef __hpux 49 | /* see http://curl.haxx.se/mail/lib-2009-04/0287.html */ 50 | typedef int network_socklen_t; 51 | #else 52 | typedef socklen_t network_socklen_t; 53 | #endif 54 | 55 | typedef struct { 56 | union { 57 | struct sockaddr_in ipv4; 58 | struct sockaddr_in6 ipv6; 59 | #ifdef HAVE_SYS_UN_H 60 | struct sockaddr_un un; 61 | #endif 62 | struct sockaddr common; 63 | } addr; 64 | 65 | GString *name; 66 | network_socklen_t len; 67 | gboolean can_unlink_socket; /* set TRUE *only* after successful bind */ 68 | } network_address; 69 | 70 | NETWORK_API network_address *network_address_new(void); 71 | NETWORK_API void network_address_free(network_address *); 72 | NETWORK_API void network_address_reset(network_address *addr); 73 | NETWORK_API network_address *network_address_copy(network_address *dst, network_address *src); 74 | NETWORK_API gint network_address_set_address(network_address *addr, const gchar *address); 75 | NETWORK_API gint network_address_refresh_name(network_address *addr); 76 | NETWORK_API gint network_address_is_local(network_address *dst_addr, network_address *src_addr); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/network-backend-lua.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef __NETWORK_BACKEND_LUA_H__ 21 | #define __NETWORK_BACKEND_LUA_H__ 22 | 23 | #include 24 | 25 | #include "network-exports.h" 26 | 27 | NETWORK_API int network_backend_lua_getmetatable(lua_State *L); 28 | NETWORK_API int network_backends_lua_getmetatable(lua_State *L); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/network-backend.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/src/network-backend.c -------------------------------------------------------------------------------- /src/network-backend.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _BACKEND_H_ 23 | #define _BACKEND_H_ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | #include "config.h" 27 | #endif 28 | 29 | #define PWD_SUCCESS 0 30 | #define ERR_USER_EXIST 1 31 | #define ERR_USER_NOT_EXIST 1 32 | #define ERR_PWD_ENCRYPT 2 33 | #define ERR_PWD_DECRYPT 2 34 | 35 | #include "network-conn-pool.h" 36 | #include "network-exports.h" 37 | 38 | typedef enum { 39 | BACKEND_STATE_UNKNOWN, 40 | BACKEND_STATE_UP, 41 | BACKEND_STATE_DOWN, 42 | BACKEND_STATE_OFFLINE 43 | } backend_state_t; 44 | 45 | typedef enum { 46 | BACKEND_TYPE_UNKNOWN, 47 | BACKEND_TYPE_RW, 48 | BACKEND_TYPE_RO 49 | } backend_type_t; 50 | 51 | typedef struct { 52 | network_address *addr; 53 | 54 | backend_state_t state; /**< UP or DOWN */ 55 | backend_type_t type; /**< ReadWrite or ReadOnly */ 56 | 57 | // GTimeVal state_since; /**< timestamp of the last state-change */ 58 | 59 | // network_connection_pool *pool; /**< the pool of open connections */ 60 | GPtrArray *pools; 61 | 62 | gint connected_clients; /**< number of open connections to this backend for SQF */ 63 | 64 | GString *uuid; /**< the UUID of the backend */ 65 | 66 | guint weight; 67 | } network_backend_t; 68 | 69 | NETWORK_API network_backend_t *network_backend_new(); 70 | NETWORK_API void network_backend_free(network_backend_t *b); 71 | 72 | typedef struct { 73 | guint max_weight; 74 | guint cur_weight; 75 | guint next_ndx; 76 | } g_wrr_poll; 77 | 78 | typedef struct { 79 | GPtrArray *backends; 80 | GMutex *backends_mutex; /*remove lock*/ 81 | g_wrr_poll *global_wrr; 82 | guint event_thread_count; 83 | gchar *default_file; 84 | GHashTable **ip_table; 85 | gint *ip_table_index; 86 | GPtrArray *raw_ips; 87 | GHashTable **pwd_table; 88 | gint *pwd_table_index; 89 | GPtrArray *raw_pwds; 90 | } network_backends_t; 91 | 92 | NETWORK_API network_backends_t *network_backends_new(guint event_thread_count, gchar *default_file); 93 | NETWORK_API void network_backends_free(network_backends_t *); 94 | NETWORK_API int network_backends_add(network_backends_t *backends, gchar *address, backend_type_t type); 95 | NETWORK_API int network_backends_remove(network_backends_t *backends, guint index); 96 | NETWORK_API int network_backends_addclient(network_backends_t *backends, gchar *address); 97 | NETWORK_API int network_backends_removeclient(network_backends_t *backends, gchar *address); 98 | NETWORK_API int network_backends_addpwd(network_backends_t *backends, gchar *user, gchar *pwd, gboolean is_encrypt); 99 | NETWORK_API int network_backends_removepwd(network_backends_t *backends, gchar *address); 100 | NETWORK_API int network_backends_check(network_backends_t *backends); 101 | NETWORK_API network_backend_t * network_backends_get(network_backends_t *backends, guint ndx); 102 | NETWORK_API guint network_backends_count(network_backends_t *backends); 103 | 104 | NETWORK_API g_wrr_poll *g_wrr_poll_new(); 105 | NETWORK_API void g_wrr_poll_free(g_wrr_poll *global_wrr); 106 | 107 | NETWORK_API char *decrypt(char *in); 108 | 109 | #endif /* _BACKEND_H_ */ 110 | -------------------------------------------------------------------------------- /src/network-conn-pool-lua.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/src/network-conn-pool-lua.c -------------------------------------------------------------------------------- /src/network-conn-pool-lua.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef __NETWORK_CONN_POOL_LUA_H__ 21 | #define __NETWORK_CONN_POOL_LUA_H__ 22 | 23 | #include 24 | 25 | #include "network-socket.h" 26 | #include "network-mysqld.h" 27 | 28 | #include "network-exports.h" 29 | 30 | NETWORK_API int network_connection_pool_getmetatable(lua_State *L); 31 | 32 | NETWORK_API int network_connection_pool_lua_add_connection(network_mysqld_con *con); 33 | NETWORK_API network_socket *network_connection_pool_lua_swap(network_mysqld_con *con, int backend_ndx, GHashTable *pwd_table); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/network-conn-pool.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _NETWORK_CONN_POOL_H_ 23 | #define _NETWORK_CONN_POOL_H_ 24 | 25 | #include 26 | 27 | #include "lua-scope.h" 28 | 29 | #include "network-socket.h" 30 | #include "network-exports.h" 31 | 32 | typedef GQueue network_connection_pool; 33 | 34 | typedef struct { 35 | network_socket *sock; /** the idling socket */ 36 | 37 | network_connection_pool *pool; /** a pointer back to the pool */ 38 | } network_connection_pool_entry; 39 | 40 | NETWORK_API network_socket *network_connection_pool_get(network_connection_pool *pool); 41 | NETWORK_API network_connection_pool_entry *network_connection_pool_add(network_connection_pool *pool, network_socket *sock); 42 | NETWORK_API void network_connection_pool_remove(network_connection_pool *pool, network_connection_pool_entry *entry); 43 | 44 | NETWORK_API network_connection_pool *network_connection_pool_new(void); 45 | NETWORK_API void network_connection_pool_free(network_connection_pool *pool); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/network-debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __NETWORK_DEBUG_H__ 2 | #define __NETWORK_DEBUG_H__ 3 | 4 | /** 5 | * if NETWORK_DEBUG_TRACE_IO is defined, the network layer will log the 6 | * raw MySQL packets as log-level "debug" 7 | * 8 | * #define NETWORK_DEBUG_TRACE_IO 1 9 | */ 10 | 11 | /** 12 | * if NETWORK_DEBUG_TRACE_STATE_CHANGES is defined the state engine for 13 | * the mysql protocol will log all state changes 14 | * 15 | * #define NETWORK_DEBUG_TRACE_STATE_CHANGES 1 16 | */ 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/network-exports.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef _NETWORK_EXPORTS_H_ 21 | #define _NETWORK_EXPORTS_H_ 22 | 23 | #if defined(_WIN32) 24 | 25 | #if defined(mysql_chassis_proxy_EXPORTS) 26 | #define NETWORK_API __declspec(dllexport) 27 | #elif defined(mysql_chassis_proxy_STATIC) /* In test cases, define this to prevent linker warnings on Win32 */ 28 | #define NETWORK_API 29 | #else 30 | #define NETWORK_API extern __declspec(dllimport) 31 | #endif 32 | 33 | #else 34 | 35 | #define NETWORK_API extern 36 | 37 | #endif 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/network-injection-lua.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _QUERY_HANDLING_LUA_H_ 23 | #define _QUERY_HANDLING_LUA_H_ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | #include "config.h" 27 | #endif 28 | 29 | /** 30 | * embedded lua support 31 | */ 32 | #include 33 | #include 34 | #include 35 | 36 | #include "network-exports.h" 37 | #include "network-injection.h" 38 | 39 | NETWORK_API void proxy_getqueuemetatable(lua_State *L); 40 | NETWORK_API void proxy_getinjectionmetatable(lua_State *L); 41 | 42 | #endif /* _QUERY_HANDLING_H_ */ 43 | -------------------------------------------------------------------------------- /src/network-injection.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #include 23 | 24 | #include "network-injection.h" 25 | 26 | #include "network-mysqld-proto.h" 27 | #include "network-mysqld-packet.h" 28 | #include "glib-ext.h" 29 | #include "lua-env.h" 30 | #include "chassis-timings.h" 31 | 32 | #define C(x) x, sizeof(x) - 1 33 | #define S(x) x->str, x->len 34 | 35 | #define TIME_DIFF_US(t2, t1) \ 36 | ((t2.tv_sec - t1.tv_sec) * 1000000.0 + (t2.tv_usec - t1.tv_usec)) 37 | 38 | 39 | /** 40 | * Initialize an injection struct. 41 | */ 42 | injection *injection_new(int id, GString *query) { 43 | injection *i; 44 | 45 | i = g_new0(injection, 1); 46 | i->id = id; 47 | i->query = query; 48 | i->resultset_is_needed = FALSE; /* don't buffer the resultset */ 49 | 50 | /** 51 | * we have to assume that injection_new() is only used by the read_query call 52 | * which should be fine 53 | */ 54 | i->ts_read_query = chassis_get_rel_microseconds(); 55 | /* g_get_current_time(&(i->ts_read_query)); */ 56 | 57 | return i; 58 | } 59 | 60 | /** 61 | * Free an injection struct 62 | */ 63 | void injection_free(injection *i) { 64 | if (!i) return; 65 | 66 | if (i->query) g_string_free(i->query, TRUE); 67 | 68 | g_free(i); 69 | } 70 | 71 | network_injection_queue *network_injection_queue_new() { 72 | return g_queue_new(); 73 | } 74 | 75 | void network_injection_queue_free(network_injection_queue *q) { 76 | if (!q) return; 77 | 78 | network_injection_queue_reset(q); 79 | 80 | g_queue_free(q); 81 | } 82 | 83 | void network_injection_queue_reset(network_injection_queue *q) { 84 | injection *inj; 85 | if (!q) return; 86 | 87 | while ((inj = g_queue_pop_head(q))) injection_free(inj); 88 | } 89 | 90 | void network_injection_queue_append(network_injection_queue *q, injection *inj) { 91 | g_queue_push_tail(q, inj); 92 | } 93 | 94 | void network_injection_queue_prepend(network_injection_queue *q, injection *inj) { 95 | g_queue_push_head(q, inj); 96 | } 97 | 98 | guint network_injection_queue_len(network_injection_queue *q) { 99 | return q->length; 100 | } 101 | /** 102 | * Initialize a resultset struct 103 | */ 104 | proxy_resultset_t *proxy_resultset_init() { 105 | return proxy_resultset_new(); 106 | } 107 | 108 | proxy_resultset_t *proxy_resultset_new() { 109 | proxy_resultset_t *res; 110 | 111 | res = g_new0(proxy_resultset_t, 1); 112 | 113 | return res; 114 | } 115 | 116 | /** 117 | * Free a resultset struct 118 | */ 119 | void proxy_resultset_free(proxy_resultset_t *res) { 120 | if (!res) return; 121 | 122 | if (res->fields) { 123 | network_mysqld_proto_fielddefs_free(res->fields); 124 | } 125 | 126 | g_free(res); 127 | } 128 | 129 | 130 | -------------------------------------------------------------------------------- /src/network-mysqld-lua.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef __NETWORK_MYSQLD_LUA__ 21 | #define __NETWORK_MYSQLD_LUA__ 22 | 23 | #include 24 | 25 | #include "network-backend.h" /* query-status */ 26 | #include "network-injection.h" /* query-status */ 27 | 28 | #include "network-exports.h" 29 | 30 | typedef enum { 31 | PROXY_NO_DECISION, 32 | PROXY_SEND_QUERY, 33 | PROXY_SEND_RESULT, 34 | PROXY_SEND_INJECTION, 35 | PROXY_IGNORE_RESULT /** for read_query_result */ 36 | } network_mysqld_lua_stmt_ret; 37 | 38 | typedef enum { 39 | REGISTER_CALLBACK_SUCCESS, 40 | REGISTER_CALLBACK_LOAD_FAILED, 41 | REGISTER_CALLBACK_EXECUTE_FAILED 42 | } network_mysqld_register_callback_ret; 43 | 44 | NETWORK_API int network_mysqld_con_getmetatable(lua_State *L); 45 | NETWORK_API void network_mysqld_lua_init_global_fenv(lua_State *L); 46 | 47 | NETWORK_API void network_mysqld_lua_setup_global(lua_State *L, chassis *chas); 48 | 49 | /** 50 | * Encapsulates injected queries information passed back from the a Lua callback function. 51 | * 52 | * @todo Simplify this structure, it should be folded into network_mysqld_con_lua_t. 53 | */ 54 | struct network_mysqld_con_lua_injection { 55 | network_injection_queue *queries; /**< An ordered list of queries we want to have executed. */ 56 | int sent_resultset; /**< Flag to make sure we send only one result back to the client. */ 57 | }; 58 | /** 59 | * Contains extra connection state used for Lua-based plugins. 60 | */ 61 | typedef struct { 62 | struct network_mysqld_con_lua_injection injected; /**< A list of queries to send to the backend.*/ 63 | 64 | lua_State *L; /**< The Lua interpreter state of the current connection. */ 65 | int L_ref; /**< The reference into the lua_scope's registry (a global structure in the Lua interpreter) */ 66 | 67 | network_backend_t *backend; 68 | int backend_ndx; /**< [lua] index into the backend-array */ 69 | 70 | gboolean connection_close; /**< [lua] set by the lua code to close a connection */ 71 | 72 | struct timeval interval; /**< The interval to be used for evt_timer, currently unused. */ 73 | struct event evt_timer; /**< The event structure used to implement the timer callback, currently unused. */ 74 | 75 | gboolean is_reconnecting; /**< if true, critical messages concerning failed connect() calls are suppressed, as they are expected errors */ 76 | } network_mysqld_con_lua_t; 77 | 78 | NETWORK_API network_mysqld_con_lua_t *network_mysqld_con_lua_new(); 79 | NETWORK_API void network_mysqld_con_lua_free(network_mysqld_con_lua_t *st); 80 | 81 | /** be sure to include network-mysqld.h */ 82 | NETWORK_API network_mysqld_register_callback_ret network_mysqld_con_lua_register_callback(network_mysqld_con *con, const char *lua_script); 83 | NETWORK_API int network_mysqld_con_lua_handle_proxy_response(network_mysqld_con *con, const char *lua_script); 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/network-mysqld-masterinfo.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef _NETWORK_MYSQLD_MASTERINFO_H_ 21 | #define _NETWORK_MYSQLD_MASTERINFO_H_ 22 | 23 | #include 24 | 25 | #include "network-exports.h" 26 | #include "network-mysqld-proto.h" 27 | 28 | typedef struct { 29 | guint32 master_lines; 30 | GString *master_log_file; 31 | guint32 master_log_pos; 32 | GString *master_host; 33 | GString *master_user; 34 | GString *master_password; 35 | guint32 master_port; 36 | guint32 master_connect_retry; 37 | 38 | guint32 master_ssl; /* if ssl is compiled in */ 39 | GString *master_ssl_ca; 40 | GString *master_ssl_capath; 41 | GString *master_ssl_cert; 42 | GString *master_ssl_cipher; 43 | GString *master_ssl_key; 44 | 45 | guint32 master_ssl_verify_server_cert; /* 5.1.16+ */ 46 | } network_mysqld_masterinfo_t; 47 | 48 | NETWORK_API network_mysqld_masterinfo_t * network_mysqld_masterinfo_new(void); 49 | NETWORK_API int network_mysqld_masterinfo_get(network_packet *packet, network_mysqld_masterinfo_t *info); 50 | NETWORK_API int network_mysqld_masterinfo_append(GString *packet, network_mysqld_masterinfo_t *info); 51 | NETWORK_API void network_mysqld_masterinfo_free(network_mysqld_masterinfo_t *info); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/network-mysqld.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qihoo360/Atlas/5082aa0403caccfdd3820007e20144e3441f8566/src/network-mysqld.c -------------------------------------------------------------------------------- /src/network-queue.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _NETWORK_QUEUE_H_ 23 | #define _NETWORK_QUEUE_H_ 24 | 25 | #include "network-exports.h" 26 | 27 | #include 28 | 29 | /* a input or output stream */ 30 | typedef struct { 31 | GQueue *chunks; 32 | 33 | size_t len; /* len in all chunks (w/o the offset) */ 34 | size_t offset; /* offset in the first chunk */ 35 | } network_queue; 36 | 37 | NETWORK_API network_queue *network_queue_init(void) G_GNUC_DEPRECATED; 38 | NETWORK_API network_queue *network_queue_new(void); 39 | NETWORK_API void network_queue_free(network_queue *queue); 40 | NETWORK_API int network_queue_append(network_queue *queue, GString *chunk); 41 | NETWORK_API GString *network_queue_pop_string(network_queue *queue, gsize steal_len, GString *dest); 42 | NETWORK_API GString *network_queue_peek_string(network_queue *queue, gsize peek_len, GString *dest); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/network-socket-lua.c: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | #include 22 | 23 | #include "lua-env.h" 24 | #include "glib-ext.h" 25 | 26 | #include "network-socket.h" 27 | #include "network-mysqld-packet.h" 28 | #include "network-address-lua.h" 29 | #include "network-socket-lua.h" 30 | 31 | #define C(x) x, sizeof(x) - 1 32 | #define S(x) x->str, x->len 33 | 34 | static int proxy_socket_get(lua_State *L) { 35 | network_socket *sock = *(network_socket **)luaL_checkself(L); 36 | gsize keysize = 0; 37 | const char *key = luaL_checklstring(L, 2, &keysize); 38 | 39 | /** 40 | * we to split it in .client and .server here 41 | */ 42 | 43 | if (strleq(key, keysize, C("default_db"))) { 44 | lua_pushlstring(L, sock->default_db->str, sock->default_db->len); 45 | return 1; 46 | }else if (strleq(key, keysize, C("charset_client"))) { 47 | lua_pushlstring(L, sock->charset_client->str, sock->charset_client->len); 48 | return 1; 49 | }else if (strleq(key, keysize, C("charset_connection"))) { 50 | lua_pushlstring(L, sock->charset_connection->str, sock->charset_connection->len); 51 | return 1; 52 | }else if (strleq(key, keysize, C("charset_results"))) { 53 | lua_pushlstring(L, sock->charset_results->str, sock->charset_results->len); 54 | return 1; 55 | }else if (strleq(key, keysize, C("address"))) { 56 | return luaL_error(L, ".address is deprecated. Use .src.name or .dst.name instead"); 57 | } else if (strleq(key, keysize, C("src"))) { 58 | return network_address_lua_push(L, sock->src); 59 | } else if (strleq(key, keysize, C("dst"))) { 60 | return network_address_lua_push(L, sock->dst); 61 | } 62 | 63 | if (sock->response) { 64 | if (strleq(key, keysize, C("username"))) { 65 | lua_pushlstring(L, S(sock->response->username)); 66 | return 1; 67 | } else if (strleq(key, keysize, C("scrambled_password"))) { 68 | lua_pushlstring(L, S(sock->response->response)); 69 | return 1; 70 | } 71 | } 72 | 73 | if (sock->challenge) { /* only the server-side has mysqld_version set */ 74 | if (strleq(key, keysize, C("mysqld_version"))) { 75 | lua_pushinteger(L, sock->challenge->server_version); 76 | return 1; 77 | } else if (strleq(key, keysize, C("thread_id"))) { 78 | lua_pushinteger(L, sock->challenge->thread_id); 79 | return 1; 80 | } else if (strleq(key, keysize, C("scramble_buffer"))) { 81 | lua_pushlstring(L, S(sock->challenge->challenge)); 82 | return 1; 83 | } 84 | } 85 | g_critical("%s: sock->challenge: %p, sock->response: %p (looking for %s)", 86 | G_STRLOC, 87 | (void *)sock->challenge, 88 | (void *)sock->response, 89 | key 90 | ); 91 | 92 | lua_pushnil(L); 93 | 94 | return 1; 95 | } 96 | 97 | int network_socket_lua_getmetatable(lua_State *L) { 98 | static const struct luaL_reg methods[] = { 99 | { "__index", proxy_socket_get }, 100 | { NULL, NULL }, 101 | }; 102 | return proxy_getmetatable(L, methods); 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/network-socket-lua.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | #ifndef __NETWORK_SOCKET_LUA_H__ 21 | #define __NETWORK_SOCKET_LUA_H__ 22 | 23 | #include 24 | 25 | #include "network-exports.h" 26 | 27 | NETWORK_API int network_socket_lua_getmetatable(lua_State *L); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/network_mysqld_proto_binary.h: -------------------------------------------------------------------------------- 1 | #ifndef __NETWORK_MYSQLD_PROTO_BINARY_H__ 2 | #define __NETWORK_MYSQLD_PROTO_BINARY_H__ 3 | 4 | #include 5 | 6 | #include "network-socket.h" 7 | #include "network_mysqld_type.h" 8 | 9 | #include "network-exports.h" 10 | 11 | NETWORK_API int network_mysqld_proto_binary_get_type(network_packet *packet, network_mysqld_type_t *type); 12 | NETWORK_API int network_mysqld_proto_binary_append_type(GString *packet, network_mysqld_type_t *type); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/proxy-dtrace-provider.d: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | provider mysqlproxy { 22 | /** 23 | * fires when the internal chassis state machine arrives at a new state. 24 | * @param event_fd File descriptor this event fired on 25 | * @param events Flags which events happened (from libevent) 26 | * @param state Connection state, enum state from network-mysqld.h 27 | */ 28 | probe state__change(int, short, int); 29 | }; 30 | -------------------------------------------------------------------------------- /src/string-len.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _GLIB_EXT_STRING_LEN_H_ 23 | #define _GLIB_EXT_STRING_LEN_H_ 24 | 25 | /** 26 | * simple macros to get the data and length of a "string" 27 | * 28 | * C() is for constant strings like "foo" 29 | * S() is for GString's 30 | */ 31 | #define C(x) x, x ? sizeof(x) - 1 : 0 32 | #define S(x) (x) ? (x)->str : NULL, (x) ? (x)->len : 0 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/sys-pedantic.h: -------------------------------------------------------------------------------- 1 | /* $%BEGINLICENSE%$ 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License as 6 | published by the Free Software Foundation; version 2 of the 7 | License. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | 02110-1301 USA 18 | 19 | $%ENDLICENSE%$ */ 20 | 21 | 22 | #ifndef _SYS_PEDANTIC_H_ 23 | #define _SYS_PEDANTIC_H_ 24 | 25 | /** @file 26 | * a set of macros to make programming C easier 27 | */ 28 | 29 | #ifdef UNUSED_PARAM 30 | #elif defined(__GNUC__) 31 | # define UNUSED_PARAM(x) UNUSED_ ## x __attribute__((unused)) 32 | #elif defined(__LCLINT__) 33 | # define UNUSED_PARAM(x) /*@unused@*/ x 34 | #else 35 | # define UNUSED_PARAM(x) x 36 | #endif 37 | 38 | #define F_SIZE_T "%"G_GSIZE_FORMAT 39 | #define F_U64 "%"G_GUINT64_FORMAT 40 | 41 | #endif 42 | --------------------------------------------------------------------------------