├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── LICENSE ├── Makefile.am ├── NEWS ├── README ├── README.md ├── bootstrap-shtool.sh ├── bootstrap.sh ├── configure.ac ├── database-schemas └── mysql │ ├── routes.sql │ ├── tables.sql │ └── users.sql ├── example-configurations ├── bearerbox.conf ├── database-only │ └── ksmppd.conf ├── http-auth-database-routing │ ├── ksmppd.conf │ └── php-example │ │ └── smpp-auth.php ├── http-only │ ├── ksmppd.conf │ └── php-example │ │ ├── smpp-auth.php │ │ └── smpp-route.php └── tests │ ├── kannel.conf │ └── ksmppd.conf ├── ksmppd.conf └── smpp ├── Makefile.am ├── ksmppd.c └── libsmpp ├── smpp_bearerbox.c ├── smpp_bearerbox.h ├── smpp_database.c ├── smpp_database.h ├── smpp_database_mysql.c ├── smpp_esme.c ├── smpp_esme.h ├── smpp_http_client.c ├── smpp_http_client.h ├── smpp_http_server.c ├── smpp_http_server.h ├── smpp_listener.c ├── smpp_listener.h ├── smpp_pdu_util.c ├── smpp_pdu_util.h ├── smpp_plugin.c ├── smpp_plugin.h ├── smpp_queued_pdu.c ├── smpp_queued_pdu.h ├── smpp_queues.c ├── smpp_queues.h ├── smpp_route.c ├── smpp_route.h ├── smpp_server.c ├── smpp_server.h ├── smpp_server_cfg.c ├── smpp_server_cfg.def ├── smpp_server_cfg.h ├── smpp_uuid.c └── smpp_uuid.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | kannel-svn-trunk 4 | nbproject 5 | smpp/ksmppd 6 | smpp/*.o 7 | smpp/libsmpp/*.o 8 | CMakeLists.txt 9 | *.a 10 | .idea 11 | *.lo 12 | *.o 13 | smpp/.libs 14 | smpp/.deps 15 | m4/ 16 | autom4te.cache/ 17 | build-aux/ 18 | Makefile 19 | Makefile.in 20 | smpp/Makefile 21 | smpp/Makefile.in 22 | configure 23 | config.h 24 | config.h.in 25 | config.log 26 | config.status 27 | libtool 28 | smpp/libsmpp.la 29 | smpp/libsmpp/.libs 30 | smpp/libsmpp/.deps 31 | smpp/libsmpp/.dirstamp 32 | aclocal.m4 33 | stamp-h1 34 | shtool* 35 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kneodev/ksmppd/c02162a8836f70d36f73aa3a914d00c692c4cd76/AUTHORS -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kneodev/ksmppd/c02162a8836f70d36f73aa3a914d00c692c4cd76/ChangeLog -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software 5 | Foundation, Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell command './configure && make && make install' 16 | should configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the 'README' file for 18 | instructions specific to this package. Some packages provide this 19 | 'INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The 'configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a 'Makefile' in each directory of the package. 27 | It may also create one or more '.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script 'config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file 'config.log' containing compiler output (useful mainly for 31 | debugging 'configure'). 32 | 33 | It can also use an optional file (typically called 'config.cache' and 34 | enabled with '--cache-file=config.cache' or simply '-C') that saves the 35 | results of its tests to speed up reconfiguring. Caching is disabled by 36 | default to prevent problems with accidental use of stale cache files. 37 | 38 | If you need to do unusual things to compile the package, please try 39 | to figure out how 'configure' could check whether to do them, and mail 40 | diffs or instructions to the address given in the 'README' so they can 41 | be considered for the next release. If you are using the cache, and at 42 | some point 'config.cache' contains results you don't want to keep, you 43 | may remove or edit it. 44 | 45 | The file 'configure.ac' (or 'configure.in') is used to create 46 | 'configure' by a program called 'autoconf'. You need 'configure.ac' if 47 | you want to change it or regenerate 'configure' using a newer version of 48 | 'autoconf'. 49 | 50 | The simplest way to compile this package is: 51 | 52 | 1. 'cd' to the directory containing the package's source code and type 53 | './configure' to configure the package for your system. 54 | 55 | Running 'configure' might take a while. While running, it prints 56 | some messages telling which features it is checking for. 57 | 58 | 2. Type 'make' to compile the package. 59 | 60 | 3. Optionally, type 'make check' to run any self-tests that come with 61 | the package, generally using the just-built uninstalled binaries. 62 | 63 | 4. Type 'make install' to install the programs and any data files and 64 | documentation. When installing into a prefix owned by root, it is 65 | recommended that the package be configured and built as a regular 66 | user, and only the 'make install' phase executed with root 67 | privileges. 68 | 69 | 5. Optionally, type 'make installcheck' to repeat any self-tests, but 70 | this time using the binaries in their final installed location. 71 | This target does not install anything. Running this target as a 72 | regular user, particularly if the prior 'make install' required 73 | root privileges, verifies that the installation completed 74 | correctly. 75 | 76 | 6. You can remove the program binaries and object files from the 77 | source code directory by typing 'make clean'. To also remove the 78 | files that 'configure' created (so you can compile the package for 79 | a different kind of computer), type 'make distclean'. There is 80 | also a 'make maintainer-clean' target, but that is intended mainly 81 | for the package's developers. If you use it, you may have to get 82 | all sorts of other programs in order to regenerate files that came 83 | with the distribution. 84 | 85 | 7. Often, you can also type 'make uninstall' to remove the installed 86 | files again. In practice, not all packages have tested that 87 | uninstallation works correctly, even though it is required by the 88 | GNU Coding Standards. 89 | 90 | 8. Some packages, particularly those that use Automake, provide 'make 91 | distcheck', which can by used by developers to test that all other 92 | targets like 'make install' and 'make uninstall' work correctly. 93 | This target is generally not run by end users. 94 | 95 | Compilers and Options 96 | ===================== 97 | 98 | Some systems require unusual options for compilation or linking that 99 | the 'configure' script does not know about. Run './configure --help' 100 | for details on some of the pertinent environment variables. 101 | 102 | You can give 'configure' initial values for configuration parameters 103 | by setting variables in the command line or in the environment. Here is 104 | an example: 105 | 106 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 107 | 108 | *Note Defining Variables::, for more details. 109 | 110 | Compiling For Multiple Architectures 111 | ==================================== 112 | 113 | You can compile the package for more than one kind of computer at the 114 | same time, by placing the object files for each architecture in their 115 | own directory. To do this, you can use GNU 'make'. 'cd' to the 116 | directory where you want the object files and executables to go and run 117 | the 'configure' script. 'configure' automatically checks for the source 118 | code in the directory that 'configure' is in and in '..'. This is known 119 | as a "VPATH" build. 120 | 121 | With a non-GNU 'make', it is safer to compile the package for one 122 | architecture at a time in the source code directory. After you have 123 | installed the package for one architecture, use 'make distclean' before 124 | reconfiguring for another architecture. 125 | 126 | On MacOS X 10.5 and later systems, you can create libraries and 127 | executables that work on multiple system types--known as "fat" or 128 | "universal" binaries--by specifying multiple '-arch' options to the 129 | compiler but only a single '-arch' option to the preprocessor. Like 130 | this: 131 | 132 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 133 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CPP="gcc -E" CXXCPP="g++ -E" 135 | 136 | This is not guaranteed to produce working output in all cases, you 137 | may have to build one architecture at a time and combine the results 138 | using the 'lipo' tool if you have problems. 139 | 140 | Installation Names 141 | ================== 142 | 143 | By default, 'make install' installs the package's commands under 144 | '/usr/local/bin', include files under '/usr/local/include', etc. You 145 | can specify an installation prefix other than '/usr/local' by giving 146 | 'configure' the option '--prefix=PREFIX', where PREFIX must be an 147 | absolute file name. 148 | 149 | You can specify separate installation prefixes for 150 | architecture-specific files and architecture-independent files. If you 151 | pass the option '--exec-prefix=PREFIX' to 'configure', the package uses 152 | PREFIX as the prefix for installing programs and libraries. 153 | Documentation and other data files still use the regular prefix. 154 | 155 | In addition, if you use an unusual directory layout you can give 156 | options like '--bindir=DIR' to specify different values for particular 157 | kinds of files. Run 'configure --help' for a list of the directories 158 | you can set and what kinds of files go in them. In general, the default 159 | for these options is expressed in terms of '${prefix}', so that 160 | specifying just '--prefix' will affect all of the other directory 161 | specifications that were not explicitly provided. 162 | 163 | The most portable way to affect installation locations is to pass the 164 | correct locations to 'configure'; however, many packages provide one or 165 | both of the following shortcuts of passing variable assignments to the 166 | 'make install' command line to change installation locations without 167 | having to reconfigure or recompile. 168 | 169 | The first method involves providing an override variable for each 170 | affected directory. For example, 'make install 171 | prefix=/alternate/directory' will choose an alternate location for all 172 | directory configuration variables that were expressed in terms of 173 | '${prefix}'. Any directories that were specified during 'configure', 174 | but not in terms of '${prefix}', must each be overridden at install time 175 | for the entire installation to be relocated. The approach of makefile 176 | variable overrides for each directory variable is required by the GNU 177 | Coding Standards, and ideally causes no recompilation. However, some 178 | platforms have known limitations with the semantics of shared libraries 179 | that end up requiring recompilation when using this method, particularly 180 | noticeable in packages that use GNU Libtool. 181 | 182 | The second method involves providing the 'DESTDIR' variable. For 183 | example, 'make install DESTDIR=/alternate/directory' will prepend 184 | '/alternate/directory' before all installation names. The approach of 185 | 'DESTDIR' overrides is not required by the GNU Coding Standards, and 186 | does not work on platforms that have drive letters. On the other hand, 187 | it does better at avoiding recompilation issues, and works well even 188 | when some directory options were not specified in terms of '${prefix}' 189 | at 'configure' time. 190 | 191 | Optional Features 192 | ================= 193 | 194 | If the package supports it, you can cause programs to be installed 195 | with an extra prefix or suffix on their names by giving 'configure' the 196 | option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. 197 | 198 | Some packages pay attention to '--enable-FEATURE' options to 199 | 'configure', where FEATURE indicates an optional part of the package. 200 | They may also pay attention to '--with-PACKAGE' options, where PACKAGE 201 | is something like 'gnu-as' or 'x' (for the X Window System). The 202 | 'README' should mention any '--enable-' and '--with-' options that the 203 | package recognizes. 204 | 205 | For packages that use the X Window System, 'configure' can usually 206 | find the X include and library files automatically, but if it doesn't, 207 | you can use the 'configure' options '--x-includes=DIR' and 208 | '--x-libraries=DIR' to specify their locations. 209 | 210 | Some packages offer the ability to configure how verbose the 211 | execution of 'make' will be. For these packages, running './configure 212 | --enable-silent-rules' sets the default to minimal output, which can be 213 | overridden with 'make V=1'; while running './configure 214 | --disable-silent-rules' sets the default to verbose, which can be 215 | overridden with 'make V=0'. 216 | 217 | Particular systems 218 | ================== 219 | 220 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC 221 | is not installed, it is recommended to use the following options in 222 | order to use an ANSI C compiler: 223 | 224 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 225 | 226 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 227 | 228 | HP-UX 'make' updates targets which have the same time stamps as their 229 | prerequisites, which makes it generally unusable when shipped generated 230 | files such as 'configure' are involved. Use GNU 'make' instead. 231 | 232 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 233 | parse its '' header file. The option '-nodtk' can be used as a 234 | workaround. If GNU CC is not installed, it is therefore recommended to 235 | try 236 | 237 | ./configure CC="cc" 238 | 239 | and if that doesn't work, try 240 | 241 | ./configure CC="cc -nodtk" 242 | 243 | On Solaris, don't put '/usr/ucb' early in your 'PATH'. This 244 | directory contains several dysfunctional programs; working variants of 245 | these programs are available in '/usr/bin'. So, if you need '/usr/ucb' 246 | in your 'PATH', put it _after_ '/usr/bin'. 247 | 248 | On Haiku, software installed for all users goes in '/boot/common', 249 | not '/usr/local'. It is recommended to use the following options: 250 | 251 | ./configure --prefix=/boot/common 252 | 253 | Specifying the System Type 254 | ========================== 255 | 256 | There may be some features 'configure' cannot figure out 257 | automatically, but needs to determine by the type of machine the package 258 | will run on. Usually, assuming the package is built to be run on the 259 | _same_ architectures, 'configure' can figure that out, but if it prints 260 | a message saying it cannot guess the machine type, give it the 261 | '--build=TYPE' option. TYPE can either be a short name for the system 262 | type, such as 'sun4', or a canonical name which has the form: 263 | 264 | CPU-COMPANY-SYSTEM 265 | 266 | where SYSTEM can have one of these forms: 267 | 268 | OS 269 | KERNEL-OS 270 | 271 | See the file 'config.sub' for the possible values of each field. If 272 | 'config.sub' isn't included in this package, then this package doesn't 273 | need to know the machine type. 274 | 275 | If you are _building_ compiler tools for cross-compiling, you should 276 | use the option '--target=TYPE' to select the type of system they will 277 | produce code for. 278 | 279 | If you want to _use_ a cross compiler, that generates code for a 280 | platform different from the build platform, you should specify the 281 | "host" platform (i.e., that on which the generated programs will 282 | eventually be run) with '--host=TYPE'. 283 | 284 | Sharing Defaults 285 | ================ 286 | 287 | If you want to set default values for 'configure' scripts to share, 288 | you can create a site shell script called 'config.site' that gives 289 | default values for variables like 'CC', 'cache_file', and 'prefix'. 290 | 'configure' looks for 'PREFIX/share/config.site' if it exists, then 291 | 'PREFIX/etc/config.site' if it exists. Or, you can set the 292 | 'CONFIG_SITE' environment variable to the location of the site script. 293 | A warning: not all 'configure' scripts look for a site script. 294 | 295 | Defining Variables 296 | ================== 297 | 298 | Variables not defined in a site shell script can be set in the 299 | environment passed to 'configure'. However, some packages may run 300 | configure again during the build, and the customized values of these 301 | variables may be lost. In order to avoid this problem, you should set 302 | them in the 'configure' command line, using 'VAR=value'. For example: 303 | 304 | ./configure CC=/usr/local2/bin/gcc 305 | 306 | causes the specified 'gcc' to be used as the C compiler (unless it is 307 | overridden in the site shell script). 308 | 309 | Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an 310 | Autoconf limitation. Until the limitation is lifted, you can use this 311 | workaround: 312 | 313 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 314 | 315 | 'configure' Invocation 316 | ====================== 317 | 318 | 'configure' recognizes the following options to control how it 319 | operates. 320 | 321 | '--help' 322 | '-h' 323 | Print a summary of all of the options to 'configure', and exit. 324 | 325 | '--help=short' 326 | '--help=recursive' 327 | Print a summary of the options unique to this package's 328 | 'configure', and exit. The 'short' variant lists options used only 329 | in the top level, while the 'recursive' variant lists options also 330 | present in any nested packages. 331 | 332 | '--version' 333 | '-V' 334 | Print the version of Autoconf used to generate the 'configure' 335 | script, and exit. 336 | 337 | '--cache-file=FILE' 338 | Enable the cache: use and save the results of the tests in FILE, 339 | traditionally 'config.cache'. FILE defaults to '/dev/null' to 340 | disable caching. 341 | 342 | '--config-cache' 343 | '-C' 344 | Alias for '--cache-file=config.cache'. 345 | 346 | '--quiet' 347 | '--silent' 348 | '-q' 349 | Do not print messages saying which checks are being made. To 350 | suppress all normal output, redirect it to '/dev/null' (any error 351 | messages will still be shown). 352 | 353 | '--srcdir=DIR' 354 | Look for the package's source code in directory DIR. Usually 355 | 'configure' can determine that directory automatically. 356 | 357 | '--prefix=DIR' 358 | Use DIR as the installation prefix. *note Installation Names:: for 359 | more details, including other options available for fine-tuning the 360 | installation locations. 361 | 362 | '--no-create' 363 | '-n' 364 | Run the configure checks, but stop before creating any output 365 | files. 366 | 367 | 'configure' also accepts some other, not widely useful, options. Run 368 | 'configure --help' for more details. 369 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | SUBDIRS = smpp 3 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kneodev/ksmppd/c02162a8836f70d36f73aa3a914d00c692c4cd76/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kneodev/ksmppd/c02162a8836f70d36f73aa3a914d00c692c4cd76/README -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### No longer maintained by Kurt. [Donald Jackson](https://github.com/donald-jackson) has taken over. 2 | 3 | # KSMPPD aka Kurt's SMPP Daemon 4 | 5 | This is my attempt at an alternative to OpenSMPPBox and the Commercial SMPPBox available 6 | 7 | I would recommend reading this page in its entiriety and then moving on to the [wiki](https://github.com/kneodev/ksmppd/wiki) for more details. 8 | 9 | What I have tried to do here is implement an SMPP server which connects to the bearerbox as currently SMSBox with the following features: 10 | 11 | * :white_check_mark: Not bound by threads per client (built with libevent) 12 | * :white_check_mark: Fast start up and regardless of workload/queues 13 | * :white_check_mark: Limited memory usage (disk based excess queue storage) 14 | * :white_check_mark: Database authentication support 15 | * :white_check_mark: Database routing support 16 | * :white_check_mark: HTTP based authentication support 17 | * :white_check_mark: HTTP based routing support 18 | * :white_check_mark: Prepaid billing support 19 | * :white_check_mark: Multiple bearerbox connections 20 | * :white_check_mark: Throttling support 21 | * :white_check_mark: Full support for simulation (delivery reports, MO, failures) 22 | * :white_check_mark: Fully asynchronous 23 | * :white_check_mark: submit_sm_resp PDU's only provided once bearerbox or database has accepted storage 24 | * :white_check_mark: HTTP routers use a callback mechanism 25 | 26 | ### TO-DO 27 | * Embeddable code (almost, just some thread joins to deal with) 28 | * others proposed via issue tracker 29 | 30 | This software will be free, forever. If you get charged for this software, please notify me. 31 | 32 | ### Acknowledgements 33 | 34 | This product includes software developed by the Kannel Group (http://www.kannel.org/). 35 | 36 | I'd also like to specifically thank the developer of OpenSMPPBox Rene Kluwen as I used some of his PDU conversion mechanisms in OpenSMPPBox. 37 | 38 | It makes extensive use of gwlib and other features developed for Kannel, it would not be possible without them. 39 | 40 | Special thanks to [donald-jackson](https://github.com/donald-jackson) for multiple contributions. 41 | 42 | If you do wish to donate to this project, please do so via the bitcoin address below. 43 | 44 | ### BTC address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 45 | 46 | ## Building 47 | 48 | Thanks to [rajesh6115](https://github.com/rajesh6115) this build can now be completed using autotools. 49 | 50 | ### Dependencies 51 | 52 | 53 | #### Kannel 54 | 55 | You need to have kannel installed with MySQL support in order to compile successfully. If you don't have kannel installed, you can do so by executing the following commands. 56 | 57 | svn co https://svn.kannel.org/gateway/trunk kannel-trunk 58 | cd kannel-trunk 59 | ./bootstrap.sh 60 | ./configure --with-mysql --enable-ssl --enable-start-stop-daemon --enable-static 61 | make 62 | sudo make install 63 | 64 | Assuming the above is done successfully (you may need to install MySQL, libxml2, etc dependencies to successfully build). 65 | 66 | #### Other dependencies 67 | 68 | libevent 69 | 70 | yum install -y libevent-devel 71 | 72 | ### Building KSMPPD 73 | 74 | Now that you have the dependencies ready you can do the following. 75 | 76 | git clone https://github.com/kneodev/ksmppd.git 77 | cd ksmppd 78 | ./bootstrap.sh 79 | 80 | If the above goes well (you will only need to bootstrap once) 81 | 82 | make 83 | 84 | You can now run using ./smpp/ksmppd. 85 | 86 | ## Using KSMPPD 87 | 88 | I have created a number of example configurations in this repository located under examples/configurations 89 | 90 | * database-only is a system that requires no HTTP server and uses a database for authentication and routing 91 | * http-auth-database-routing uses an HTTP request to authenticate ESME's and a database for routing 92 | * http-only uses HTTP for both authentication and routing. 93 | 94 | If using a database in any of the above examples, you will need to create the table schemas at a minimum located under database-schemas in this repository. 95 | 96 | There are commands available via the built in HTTP server which allow you to perform certain tasks. Appending ".xml" to commands will produce output in XML format. 97 | 98 | http://ksmppdhost:port/esme-status 99 | 100 | curl "http://localhost:14010/esme-status?password=ksmppdpass" 101 | Summary: 102 | 103 | Unique known ESME's: 3 104 | Total inbound processed:0 load: 0.00/0.00/0.00/sec 105 | Total outbound processed:0 load: 0.00/0.00/0.00/sec 106 | 107 | smppusera - binds:4/0, total inbound load:(0.00/0.00/0.00)/11.00/sec, outbound load:(0.00/0.00/0.00)/sec 108 | -- id:4 uptime:0d 0h 0m 11s, type:2, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 109 | -- id:3 uptime:0d 0h 0m 11s, type:2, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 110 | -- id:9 uptime:0d 0h 0m 10s, type:1, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 111 | -- id:8 uptime:0d 0h 0m 10s, type:1, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 112 | 113 | smppuserb - binds:2/2, total inbound load:(0.00/0.00/0.00)/0.00/sec, outbound load:(0.00/0.00/0.00)/sec 114 | -- id:0 uptime:0d 0h 0m 13s, type:1, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 115 | -- id:1 uptime:0d 0h 0m 12s, type:2, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 116 | 117 | smppuserc - binds:2/0, total inbound load:(0.00/0.00/0.00)/0.00/sec, outbound load:(0.00/0.00/0.00)/sec 118 | -- id:2 uptime:0d 0h 0m 11s, type:2, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 119 | -- id:5 uptime:0d 0h 0m 11s, type:1, open-acks:0, inbound (load/queued/processed/routing):0.00/0/1/0, outbound (load/queued/processed):0.00/0/1 120 | 121 | http://ksmppdhost:port/esme-unbind 122 | 123 | curl "http://localhost:14010/esme-unbind?password=ksmppdpass&system-id=smppuserb&bind-id=1" 124 | 1 binds disconnected 125 | curl "http://localhost:14010/esme-unbind?password=ksmppdpass&system-id=smppuserb" 126 | 2 binds disconnected 127 | 128 | http://ksmppd:port/rebuild-routes (you MUST run this if you change routes in the database) 129 | 130 | curl "http://localhost:14010/rebuild-routes?password=ksmppdpass 131 | Routes updated 132 | 133 | ## Performance 134 | 135 | Benchmarks on a Core i5 @ 3.2 GHz this software processes 1534 messages per second (more thorough benchmarks later). 136 | 137 | KSMPPD has been thoroughly tested for memory leaks in all scenarios and all have been dealt with that have been found. 138 | 139 | ## Contributing 140 | 141 | Please create issues or pull requests here to contribute. 142 | 143 | ## Behaviour 144 | 145 | At this stage I have determined optimal configuration to be with a database queue enabled. This enables better handling of failure in cases where ESME's are offline or bearerbox is unavailable. 146 | 147 | All scenarios will allow ESME's to authenticate as normal, unless the database is down. 148 | 149 | ### Some scenarios 150 | 151 | #### There are no bearerbox connections alive for deliver of messages. 152 | 153 | * submit_sm (message submissions) will be queued to the database for later delivery and successful responses returned. 154 | * Any queued MO/DLR's from a previously alive bearerbox will be forwarded to connected ESME's. 155 | 156 | #### At least one bearerbox is alive but no ESME's (or some receivers) are not available 157 | * MO/DLR's received from bearerbox will be attempt to be routed to a target receiver ESME - if not available they will be queued to try later. 158 | * Once a previously unavailable ESME becomes available, pending MO/DLR's will be forwarded. 159 | * It's important to note that there is an 'open ack' limit to ESME's, and if an ESME hits this limit, messages will begin being queued to the database. 160 | 161 | #### System is behaving as normal (database up, bearerbox(s) up, ESME's available) 162 | * If a bearerbox rejects a message (invalid routing, etc) - the ESME will get this result immediately via submit_sm_resp 163 | * If permanent routing failure for MO (eg: no routes) messages will be discarded and bearerbox notified accordingly (ack_failed) 164 | * If an ESME exceeds their max allowed open acks, messages will be queued to the database and requeued as space becomes available. This is to solve excessive memory use. 165 | 166 | #### System restart 167 | * The system first starts, connects to bearerbox and allows connections from ESMEs. Once started it begins reprocessing bearerbox queues if any. 168 | * Once ESME's reconnect - their queued messages (in database) will begin being reprocessed. 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /bootstrap-shtool.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | curl -O -L "ftp://ftp.gnu.org/gnu/shtool/shtool-2.0.8.tar.gz" 4 | 5 | tar zxvf shtool-2.0.8.tar.gz 6 | cd shtool-2.0.8 7 | 8 | ./configure 9 | make 10 | 11 | sudo make install 12 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | autoreconf -iv 4 | 5 | ./bootstrap-shtool.sh 6 | 7 | echo "Bootstrapping done, you can now run ./configure" 8 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Autoconf Minimum Version Required Check 2 | AC_PREREQ([2.68]) 3 | # Initilise Autoconf with project Name and Version Details 4 | AC_INIT([ksmppd], [1.4.4], [kneodev@gmail.com], [ksmppd], [https://github.com/kneodev/ksmppd]) 5 | # Put autotools auxiliary files in a subdir, so they don't clutter top dir: 6 | AC_CONFIG_AUX_DIR([build-aux]) 7 | # Initialise Automake with Default version Number and Default CPP flags 8 | AM_INIT_AUTOMAKE([1.11 -Wall -Werror subdir-objects]) 9 | # Check for some Unique file in the Project 10 | AC_CONFIG_SRCDIR([smpp/]) 11 | # Check for C Compiler 12 | AC_PROG_CC 13 | AC_PROG_CC_C99 14 | # config.h will be created and default header 15 | AC_CONFIG_HEADERS([config.h]) 16 | # all Macro in this folder 17 | AC_CONFIG_MACRO_DIR([m4]) 18 | # AR required to create static library 19 | AM_PROG_AR 20 | # Silence warning: ar: 'u' modifier ignored since 'D' is the default 21 | AC_SUBST(AR_FLAGS, [cr]) 22 | # libtool Required 23 | LT_PREREQ([2.2]) 24 | LT_INIT([dlopen]) 25 | AC_LIBTOOL_DLOPEN 26 | AC_PROG_LIBTOOL 27 | # Check of library created using ranlib 28 | #AC_PROG_RANLIB 29 | AC_ENABLE_SHARED 30 | # Check for pthread 31 | AC_CHECK_LIB(pthread, pthread_create,[AC_DEFINE(ENABLE_THREADS, 1, [Define this to enable threads.])],[AC_MSG_ERROR([required library pthread missing])]) 32 | # libtool Required 33 | LT_PREREQ([2.2]) 34 | LT_INIT([dlopen]) 35 | AC_ENABLE_SHARED 36 | AC_PROG_LIBTOOL(libtool) 37 | AC_MSG_NOTICE([Checking for libevent2 and its requirements.]) 38 | PKG_CHECK_MODULES([libxml2], [libxml-2.0], with_libxml2=yes, with_libxml2=no) 39 | if test "$with_libxml2" == "no" 40 | then 41 | AC_MSG_ERROR([libxml2 library not found ]) 42 | exit 1 43 | fi 44 | # check for libevent library 45 | AC_MSG_NOTICE([Checking for libevent2 and its requirements.]) 46 | PKG_CHECK_MODULES([libevent], [libevent >= 2.0], with_libevent=yes, with_libevent=no) 47 | if test "$with_libevent" == "no" 48 | then 49 | AC_MSG_ERROR([libevent library not found ]) 50 | exit 1 51 | fi 52 | 53 | #check for shtool required to extract platform 54 | AC_CHECK_PROG(SHTOOL_CHECK, shtool, yes) 55 | if test x"$SHTOOL_CHECK" != x"yes" ; then 56 | AC_MSG_ERROR([Please install shtool before installing.]) 57 | fi 58 | PLATFORMINFO=`shtool platform -S "-" -F "%-%" --lower` 59 | AC_DEFINE_UNQUOTED(PLATFORMINFO,"$PLATFORMINFO",[platform version]) 60 | 61 | AC_CHECK_PROG(GWCONFIG_CHECK, gw-config, yes) 62 | if test x"$GWCONFIG_CHECK" != x"yes" ; then 63 | AC_MSG_ERROR([Please install kannel gw-config before installing.]) 64 | fi 65 | # define GIT_VERSION 66 | AC_CHECK_PROG(GIT_CHECK, git, yes) 67 | if test x"$GIT_CHECK" != x"yes" ; then 68 | AC_MSG_ERROR([Please install git before installing.]) 69 | fi 70 | GITVERSION=`git describe --always --tags` 71 | AC_DEFINE_UNQUOTED(GITVERSION,"$GITVERSION",[git version]) 72 | # Generate These Files for Sucessfully Build 73 | AC_CONFIG_FILES([ 74 | Makefile 75 | smpp/Makefile 76 | ]) 77 | AC_OUTPUT 78 | 79 | -------------------------------------------------------------------------------- /database-schemas/mysql/routes.sql: -------------------------------------------------------------------------------- 1 | 2 | -- This is a sample SQL set to create some example routes 3 | 4 | -- Direction = 1 = outbound messages 5 | -- Direction = 2 = inbound messages 6 | 7 | -- In this example, outbound messages for smppuserA are routed via ksmppd2 if they begin with 1800 8 | -- In this example, outbound messages for smppuserA are routed via ksmppd3 if they begin with 7800 9 | -- In this example, inbound messages with the destination 6800 are routed to smppuserA 10 | 11 | INSERT INTO 12 | `smpp_route` 13 | (`route_id`, `direction`, `regex`, `cost`, `system_id`, `smsc_id`) 14 | VALUES 15 | (1,1,'^(1800)',1,'smppusera','ksmppd2'), 16 | (2,1,'^(7800)',1,'smppusera','ksmppd3'), 17 | (3,2,'^(6800)',NULL,'smppusera','ksmppd3'); 18 | -------------------------------------------------------------------------------- /database-schemas/mysql/tables.sql: -------------------------------------------------------------------------------- 1 | 2 | CREATE TABLE `smpp_queued_pdu` ( 3 | `global_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 4 | `system_id` varchar(64) NOT NULL, 5 | `time` bigint(20) DEFAULT NULL, 6 | `pdu` blob, 7 | PRIMARY KEY (`global_id`), 8 | KEY `system_id` (`system_id`) 9 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 10 | 11 | 12 | CREATE TABLE `smpp_route` ( 13 | `route_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 14 | `direction` int(11) NOT NULL, 15 | `regex` text, 16 | `cost` double DEFAULT NULL, 17 | `system_id` varchar(64) DEFAULT NULL, 18 | `smsc_id` varchar(64) DEFAULT NULL, 19 | PRIMARY KEY (`route_id`), 20 | KEY `direction` (`direction`), 21 | KEY `system_id` (`system_id`), 22 | KEY `smsc_id` (`smsc_id`) 23 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 24 | 25 | CREATE TABLE `smpp_store` ( 26 | `global_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 27 | `sender` text, 28 | `receiver` text, 29 | `udhdata` text, 30 | `msgdata` text, 31 | `time` bigint(20) NOT NULL, 32 | `smsc_id` text, 33 | `smsc_number` text, 34 | `foreign_id` text, 35 | `service` text, 36 | `account` text, 37 | `id` varchar(128) DEFAULT NULL, 38 | `sms_type` bigint(20) NOT NULL, 39 | `mclass` bigint(20) NOT NULL, 40 | `mwi` bigint(20) NOT NULL, 41 | `coding` bigint(20) NOT NULL, 42 | `compress` bigint(20) NOT NULL, 43 | `validity` bigint(20) NOT NULL, 44 | `deferred` bigint(20) NOT NULL, 45 | `dlr_mask` bigint(20) NOT NULL, 46 | `dlr_url` text, 47 | `pid` bigint(20) NOT NULL, 48 | `alt_dcs` bigint(20) NOT NULL, 49 | `rpi` bigint(20) NOT NULL, 50 | `charset` text, 51 | `boxc_id` text, 52 | `binfo` text, 53 | `msg_left` bigint(20) NOT NULL, 54 | `priority` bigint(20) NOT NULL, 55 | `resend_try` bigint(20) NOT NULL, 56 | `resend_time` bigint(20) NOT NULL, 57 | `meta_data` text, 58 | PRIMARY KEY (`global_id`), 59 | KEY `service` (`service`(16)), 60 | KEY `sms_type` (`sms_type`) 61 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 62 | 63 | CREATE TABLE `smpp_user` ( 64 | `system_id` varchar(15) NOT NULL, 65 | `password` varchar(64) NOT NULL, 66 | `throughput` double(10,5) NOT NULL DEFAULT '0.00000', 67 | `default_smsc` varchar(64) DEFAULT NULL, 68 | `default_cost` double NOT NULL, 69 | `enable_prepaid_billing` int(10) unsigned NOT NULL DEFAULT '0', 70 | `credit` double NOT NULL DEFAULT '0', 71 | `callback_url` varchar(255) DEFAULT NULL, 72 | `simulate` tinyint(1) NOT NULL DEFAULT '0', 73 | `simulate_deliver_every` int(10) unsigned NOT NULL, 74 | `simulate_permanent_failure_every` int(10) unsigned NOT NULL, 75 | `simulate_temporary_failure_every` int(10) unsigned NOT NULL, 76 | `simulate_mo_every` int(10) unsigned NOT NULL, 77 | `max_binds` int(10) unsigned NOT NULL DEFAULT '0', 78 | `connect_allow_ip` text, 79 | PRIMARY KEY (`system_id`) 80 | ) ENGINE=InnoDB; 81 | -------------------------------------------------------------------------------- /database-schemas/mysql/users.sql: -------------------------------------------------------------------------------- 1 | 2 | 3 | -- This sample creates 3 users 4 | 5 | -- smppuserA - is a prepaid billing user with a balance of 10 6 | -- smppuserB - is a post-paid billing user (no balance) 7 | -- smppuserC - is a simulated user (only simulations) 8 | 9 | INSERT INTO `smpp_user` 10 | (`system_id`, `password`, `throughput`, `default_smsc`, `default_cost`, `enable_prepaid_billing`, `credit`, 11 | `callback_url`, `simulate`, `simulate_deliver_every`, `simulate_permanent_failure_every`, `simulate_temporary_failure_every`, 12 | `simulate_mo_every`, `max_binds`) 13 | VALUES 14 | ('smppuserA',PASSWORD('userA'),11.00000,'ksmppd2',0,1,0,NULL,0,0,0,0,0,0), 15 | ('smppuserB',PASSWORD('userB'),0.00000,NULL,0,0,0,NULL,1,1,0,0,0,2), 16 | ('smppuserC',PASSWORD('userC'),0.00000,NULL,0,0,0,NULL,1,1,0,0,2,0); 17 | -------------------------------------------------------------------------------- /example-configurations/bearerbox.conf: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # This configuration has a bearerbox with 3 SMSC connections, all loop backs to KSMPPD. 4 | # 5 | # This can be used to test all examples. 6 | # 7 | # You can optionally start an SMSBOX instance to inject messages into the system. 8 | # 9 | 10 | group = core 11 | admin-port = 14000 12 | smsbox-port = 14001 13 | admin-password = bar 14 | log-file = "/tmp/kannel.log" 15 | log-level = 0 16 | box-deny-ip = "*.*.*.*" 17 | box-allow-ip = "127.0.0.1" 18 | 19 | 20 | group=smsbox-route 21 | smsbox-id=KSMPPD 22 | smsc-id=ksmppd3 23 | 24 | 25 | #--------------------------------------------- 26 | # SMSC CONNECTIONS 27 | # 28 | # These are loop back connections to KSMPPD 29 | #--------------------------------------------- 30 | 31 | group = smsc 32 | smsc = smpp 33 | smsc-id = ksmppd1 34 | port = 2345 35 | host=localhost 36 | system-type=SMPP 37 | smsc-username=smppuserA 38 | smsc-password=userA 39 | allowed-smsc-id=ksmppd1 40 | throughput=11 41 | 42 | group = smsc 43 | smsc = smpp 44 | smsc-id = ksmppd1 45 | receive-port = 2345 46 | host=localhost 47 | system-type=SMPP 48 | smsc-username=smppuserA 49 | smsc-password=userA 50 | allowed-smsc-id=ksmppd1 51 | 52 | group = smsc 53 | smsc = smpp 54 | smsc-id = ksmppd1 55 | port = 2345 56 | host=localhost 57 | system-type=SMPP 58 | smsc-username=smppuserA 59 | smsc-password=userA 60 | allowed-smsc-id=ksmppd1 61 | throughput=11 62 | 63 | group = smsc 64 | smsc = smpp 65 | smsc-id = ksmppd1 66 | receive-port = 2345 67 | host=localhost 68 | system-type=SMPP 69 | smsc-username=smppuserA 70 | smsc-password=userA 71 | allowed-smsc-id=ksmppd1 72 | 73 | group = smsc 74 | smsc = smpp 75 | smsc-id = ksmppd2 76 | port = 2345 77 | host=localhost 78 | system-type=SMPP 79 | smsc-username=smppuserB 80 | smsc-password=userB 81 | allowed-smsc-id=ksmppd2 82 | 83 | group = smsc 84 | smsc = smpp 85 | smsc-id = ksmppd2 86 | receive-port = 2345 87 | host=localhost 88 | system-type=SMPP 89 | smsc-username=smppuserB 90 | smsc-password=userB 91 | allowed-smsc-id=ksmppd2 92 | 93 | group = smsc 94 | smsc = smpp 95 | smsc-id = ksmppd2 96 | port = 2345 97 | host=localhost 98 | system-type=SMPP 99 | smsc-username=smppuserB 100 | smsc-password=userB 101 | allowed-smsc-id=ksmppd2 102 | 103 | group = smsc 104 | smsc = smpp 105 | smsc-id = ksmppd2 106 | receive-port = 2345 107 | host=localhost 108 | system-type=SMPP 109 | smsc-username=smppuserB 110 | smsc-password=userB 111 | allowed-smsc-id=ksmppd2 112 | 113 | group = smsc 114 | smsc = smpp 115 | smsc-id = ksmppd3 116 | port = 2345 117 | host=localhost 118 | system-type=SMPP 119 | smsc-username=smppuserC 120 | smsc-password=userC 121 | allowed-smsc-id=ksmppd3 122 | 123 | group = smsc 124 | smsc = smpp 125 | smsc-id = ksmppd3 126 | receive-port = 2345 127 | host=localhost 128 | system-type=SMPP 129 | smsc-username=smppuserC 130 | smsc-password=userC 131 | allowed-smsc-id=ksmppd3 132 | 133 | 134 | 135 | 136 | 137 | #--------------------------------------------- 138 | # SMSBOX SETUP 139 | # 140 | # Smsbox(es) do higher-level SMS handling after they have been received from 141 | # SMS centers by bearerbox, or before they are given to bearerbox for delivery 142 | 143 | group = smsbox 144 | bearerbox-host = 127.0.0.1 145 | sendsms-port = 14013 146 | global-sender = 14013 147 | #sendsms-chars = "0123456789 +-" 148 | #log-file = "/tmp/smsbox.log" 149 | #log-level = 0 150 | #access-log = "/tmp/access.log" 151 | 152 | #--------------------------------------------- 153 | # SEND-SMS USERS 154 | # 155 | # These users are used when Kannel smsbox sendsms interface is used to 156 | # send PUSH sms messages, i.e. calling URL like 157 | # http://kannel.machine:14013/cgi-bin/sendsms?username=tester&password=foobar... 158 | 159 | group = sendsms-user 160 | username = tester 161 | password = foobar 162 | concatenation=yes 163 | max-messages=8 164 | #user-deny-ip = "" 165 | #user-allow-ip = "" 166 | 167 | #--------------------------------------------- 168 | # SERVICES 169 | # 170 | # These are 'responses' to sms PULL messages, i.e. messages arriving from 171 | # handsets. The response is based on message content. Only one sms-service is 172 | # applied, using the first one to match. 173 | 174 | group = sms-service 175 | keyword = default 176 | exec="echo Got message > /tmp/msgs.txt" 177 | catch-all=yes 178 | omit-empty=yes 179 | -------------------------------------------------------------------------------- /example-configurations/database-only/ksmppd.conf: -------------------------------------------------------------------------------- 1 | # Sample configuration for ksmppd 2 | # Uses database for all functionality (authentication + routing) 3 | # 4 | 5 | group=ksmppd 6 | log-file=/tmp/ksmppd.log 7 | log-level=0 8 | smpp-port=2345 9 | database-type=mysql 10 | database-config=demo 11 | database-enable-queue=1 12 | id=KANNELSMPP 13 | inbound-queue-threads=4 14 | outbound-queue-threads=4 15 | # 1 = Database 16 | auth-method=1 17 | 18 | group=mysql-connection 19 | id=demo 20 | host=localhost 21 | username=demouser 22 | password=demopass 23 | database=kannel_smpp_demo 24 | max-connections=5 25 | 26 | # You can have multiple bearerbox connections if you wish 27 | group=bearerbox-connection 28 | id=KSMPPD 29 | host=localhost 30 | port=14001 31 | 32 | group=http-server 33 | port=14010 34 | password=ksmppdpass 35 | 36 | group=smpp-routing 37 | # 1 = Database 38 | routing-method=1 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example-configurations/http-auth-database-routing/ksmppd.conf: -------------------------------------------------------------------------------- 1 | 2 | # Sample configuration for ksmppd 3 | # Uses database for all functionality (authentication + routing) 4 | # 5 | 6 | group=ksmppd 7 | log-file=/tmp/ksmppd.log 8 | log-level=0 9 | smpp-port=2345 10 | database-type=mysql 11 | database-config=demo 12 | database-enable-queue=1 13 | id=KANNELSMPP 14 | inbound-queue-threads=4 15 | outbound-queue-threads=4 16 | # 2 = HTTP 17 | auth-method=2 18 | auth-url="http://localhost/smpp-auth.php" 19 | 20 | group=mysql-connection 21 | id=demo 22 | host=localhost 23 | username=demouser 24 | password=demopass 25 | database=kannel_smpp_demo 26 | max-connections=5 27 | 28 | # You can have multiple bearerbox connections if you wish 29 | group=bearerbox-connection 30 | id=KSMPPD 31 | host=localhost 32 | port=14001 33 | 34 | group=http-server 35 | port=14010 36 | password=ksmppdpass 37 | 38 | group=smpp-routing 39 | # 1 = Database 40 | routing-method=1 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /example-configurations/http-auth-database-routing/php-example/smpp-auth.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'X-KSMPPD-Auth: 1', 'X-KSMPPD-Throughput: 10', 'X-KSMPPD-Max-Binds: 2', 'X-KSMPPD-Connect-Allow-IP: *.*.*.*' 22 | ), 23 | 'smppuserB:userB' => array( 24 | 'X-KSMPPD-Auth: 1', 'X-KSMPPD-Throughput: 10', 'X-KSMPPD-Max-Binds: 2' 25 | ), 26 | 'smppuserC:userC' => array( 27 | 'X-KSMPPD-Auth: 1', 'X-KSMPPD-Simulate: 1', 'X-KSMPPD-Simulate-Deliver-Every: 1', 'X-KSMPPD-Simulate-MO-Every: 10', 'X-KSMPPD-Permanent-Failure-Every: 50', 'X-KSMPPD-Temporary-Failure-Every: 50' 28 | ) 29 | ); 30 | 31 | if(isset($headers[$systemIdHeader]) && isset($headers[$passwordHeader])) { 32 | $key = $headers[$systemIdHeader].':'.$headers[$passwordHeader]; 33 | 34 | if(isset($users[$key])) { 35 | foreach($users[$key] as $header) { 36 | Header($header); 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /example-configurations/http-only/ksmppd.conf: -------------------------------------------------------------------------------- 1 | 2 | # Sample configuration for ksmppd 3 | # Uses database for all functionality (authentication + routing) 4 | # 5 | 6 | group=ksmppd 7 | log-file=/tmp/ksmppd.log 8 | log-level=0 9 | smpp-port=2345 10 | database-type=mysql 11 | database-config=demo 12 | database-enable-queue=1 13 | id=KANNELSMPP 14 | inbound-queue-threads=4 15 | outbound-queue-threads=4 16 | # 2 = HTTP 17 | auth-method=2 18 | auth-url="http://localhost/smpp-auth.php" 19 | 20 | group=mysql-connection 21 | id=demo 22 | host=localhost 23 | username=demouser 24 | password=demopass 25 | database=kannel_smpp_demo 26 | max-connections=5 27 | 28 | # You can have multiple bearerbox connections if you wish 29 | group=bearerbox-connection 30 | id=KSMPPD 31 | host=localhost 32 | port=14001 33 | 34 | group=http-server 35 | port=14010 36 | password=ksmppdpass 37 | 38 | group=smpp-routing 39 | # 2 = HTTP 40 | routing-method=1 41 | http-routing-url="http://localhost/smpp-route.php" 42 | http-num-callers=1 43 | http-max-outstanding-requests=512 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /example-configurations/http-only/php-example/smpp-auth.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'X-KSMPPD-Auth: 1', 'X-KSMPPD-Throughput: 10', 'X-KSMPPD-Max-Binds: 2', 'X-KSMPPD-Connect-Allow-IP: *.*.*.*' 22 | ), 23 | 'smppuserB:userB' => array( 24 | 'X-KSMPPD-Auth: 1', 'X-KSMPPD-Throughput: 10', 'X-KSMPPD-Max-Binds: 2' 25 | ), 26 | 'smppuserC:userC' => array( 27 | 'X-KSMPPD-Auth: 1', 'X-KSMPPD-Simulate: 1', 'X-KSMPPD-Simulate-Deliver-Every: 1', 'X-KSMPPD-Simulate-MO-Every: 10', 'X-KSMPPD-Permanent-Failure-Every: 50', 'X-KSMPPD-Temporary-Failure-Every: 50' 28 | ) 29 | ); 30 | 31 | if(isset($headers[$systemIdHeader]) && isset($headers[$passwordHeader])) { 32 | $key = $headers[$systemIdHeader].':'.$headers[$passwordHeader]; 33 | 34 | if(isset($users[$key])) { 35 | foreach($users[$key] as $header) { 36 | Header($header); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /example-configurations/http-only/php-example/smpp-route.php: -------------------------------------------------------------------------------- 1 | 2 | '%3Fsmpp%3F', 12 | 'X-Ksmppd-Resend-Time' => '-1', 13 | 'X-Ksmppd-Resend-Try' => '-1', 14 | 'X-Ksmppd-Priority' => '0', 15 | 'X-Ksmppd-Msg-Left' => '-1', 16 | 'X-Ksmppd-Binfo' => '(null)', 17 | 'X-Ksmppd-Boxc-Id' => '(null)', 18 | 'X-Ksmppd-Charset' => '(null)', 19 | 'X-Ksmppd-Rpi' => '-1', 20 | 'X-Ksmppd-Alt-Dcs' => '0', 21 | 'X-Ksmppd-Pid' => '0', 22 | 'X-Ksmppd-Dlr-Url' => 'smppusera%7C1468405837%7C7a9a1271-7ed4-4c6f-af6f-8652252010ab', 23 | 'X-Ksmppd-Dlr-Mask' => '19', 24 | 'X-Ksmppd-Deferred' => '-1', 25 | 'X-Ksmppd-Validity' => '-1', 26 | 'X-Ksmppd-Compress' => '0', 27 | 'X-Ksmppd-Coding' => '0', 28 | 'X-Ksmppd-Mwi' => '-1', 29 | 'X-Ksmppd-Mclass' => '-1', 30 | 'X-Ksmppd-Sms-Type' => '2', 31 | 'X-Ksmppd-Id' => '7a9a1271-7ed4-4c6f-af6f-8652252010ab', 32 | 'X-Ksmppd-Account' => '(null)', 33 | 'X-Ksmppd-Service' => 'smppusera', 34 | 'X-Ksmppd-Foreign-Id' => '(null)', 35 | 'X-Ksmppd-Smsc-Number' => '(null)', 36 | 'X-Ksmppd-Smsc-Id' => '(null)', 37 | 'X-Ksmppd-Time' => '-1', 38 | 'X-Ksmppd-Msgdata' => 'Hello', 39 | 'X-Ksmppd-Udhdata' => '(null)', 40 | 'X-Ksmppd-Receiver' => '1800123', 41 | 'X-Ksmppd-Sender' => 'userD', 42 | 'X-Ksmppd-Routing-Direction' => '1' 43 | ); 44 | 45 | $allHeaderKeys = array( 46 | "X-Ksmppd-Meta-Data", 47 | "X-Ksmppd-Resend-Time", 48 | "X-Ksmppd-Resend-Try", 49 | "X-Ksmppd-Priority", 50 | "X-Ksmppd-Msg-Left", 51 | "X-Ksmppd-Binfo", 52 | "X-Ksmppd-Boxc-Id", 53 | "X-Ksmppd-Charset", 54 | "X-Ksmppd-Rpi", 55 | "X-Ksmppd-Alt-Dcs", 56 | "X-Ksmppd-Pid", 57 | "X-Ksmppd-Dlr-Url", 58 | "X-Ksmppd-Dlr-Mask", 59 | "X-Ksmppd-Deferred", 60 | "X-Ksmppd-Validity", 61 | "X-Ksmppd-Compress", 62 | "X-Ksmppd-Coding", 63 | "X-Ksmppd-Mwi", 64 | "X-Ksmppd-Mclass", 65 | "X-Ksmppd-Sms-Type", 66 | "X-Ksmppd-Id", 67 | "X-Ksmppd-Account", 68 | "X-Ksmppd-Service", 69 | "X-Ksmppd-Foreign-Id", 70 | "X-Ksmppd-Smsc-Number", 71 | "X-Ksmppd-Smsc-Id", 72 | "X-Ksmppd-Time", 73 | "X-Ksmppd-Msgdata", 74 | "X-Ksmppd-Udhdata", 75 | "X-Ksmppd-Receiver", 76 | "X-Ksmppd-Sender", 77 | "X-Ksmppd-Routing-Direction" 78 | ); 79 | 80 | 81 | 82 | Header("X-KSMPPD-Route-Status: 1"); /* Must be non-zero to indicate OK */ 83 | Header("X-KSMPPD-Route-Cost: 1.0"); /* Mandatory (even if not used), must be a number */ 84 | 85 | if($headers['X-Ksmppd-Routing-Direction'] == ROUTE_DIRECTION_OUTBOUND) { 86 | Header("X-KSMPPD-SMSC-ID: ksmppd3"); /* The SMSC ID you require to route to */ 87 | } else if($headers['X-Ksmppd-Routing-Direction'] == ROUTE_DIRECTION_INBOUND) { 88 | Header("X-KSMPPD-Service: smppusera"); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /example-configurations/tests/kannel.conf: -------------------------------------------------------------------------------- 1 | 2 | group = core 3 | admin-port = 13000 4 | smsbox-port = 13001 5 | admin-password = bar 6 | box-deny-ip = "*.*.*.*" 7 | box-allow-ip = "127.0.0.1" 8 | 9 | group = smsc 10 | smsc = fake 11 | smsc-id = FAKE 12 | port = 40000 13 | connect-allow-ip = 127.0.0.1 14 | 15 | group=smsc 16 | smsc=smpp 17 | smsc-id=ksmppd-loop-a 18 | port=2345 19 | host=localhost 20 | smsc-username=smppuserA 21 | smsc-password=smppassA 22 | system-type=VMA 23 | allowed-smsc-id=ksmppd-loop-a 24 | 25 | group=smsc 26 | smsc=smpp 27 | smsc-id=ksmppd-loop-b 28 | port=2345 29 | host=localhost 30 | smsc-username=smppuserB 31 | smsc-password=smppassB 32 | system-type=VMA 33 | allowed-smsc-id=ksmppd-loop-b 34 | 35 | group = smsbox 36 | bearerbox-host = 127.0.0.1 37 | sendsms-port = 13013 38 | global-sender = 13013 39 | #sendsms-chars = "0123456789 +-" 40 | #log-file = "/tmp/smsbox.log" 41 | #log-level = 0 42 | #access-log = "/tmp/access.log" 43 | 44 | group = sendsms-user 45 | username = tester 46 | password = foobar 47 | -------------------------------------------------------------------------------- /example-configurations/tests/ksmppd.conf: -------------------------------------------------------------------------------- 1 | # CREATE DATABASE ksmppd; 2 | # grant all privileges on ksmppd.* to 'ksmppduser'@'localhost' identified by 'ksmppdpass'; 3 | # INSERT INTO smpp_user (system_id, password) VALUES ('smppuserA', PASSWORD('smppassA')); 4 | # INSERT INTO smpp_user (system_id, password, simulate, simulate_deliver_every) VALUES ('smppuserB', PASSWORD('smppassB'), 1,1); 5 | 6 | group=ksmppd 7 | log-file=/tmp/ksmppd.log 8 | log-level=0 9 | smpp-port=2345 10 | database-type=mysql 11 | database-config=demo 12 | database-enable-queue=1 13 | id=KANNELSMPP 14 | inbound-queue-threads=4 15 | outbound-queue-threads=4 16 | # 1 = Database 17 | auth-method=1 18 | 19 | group=mysql-connection 20 | id=demo 21 | host=localhost 22 | username=ksmppduser 23 | password=ksmppdpass 24 | database=ksmppd 25 | max-connections=5 26 | 27 | group=bearerbox-connection 28 | id=KSMPPD 29 | host=localhost 30 | port=13001 31 | 32 | group=http-server 33 | port=14010 34 | password=ksmppdpass 35 | 36 | group=smpp-routing 37 | routing-method=1 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ksmppd.conf: -------------------------------------------------------------------------------- 1 | # Sample configuration for ksmppd 2 | # Uses database for all functionality (authentication + routing) 3 | # 4 | 5 | group=ksmppd 6 | log-file=/tmp/ksmppd.log 7 | log-level=0 8 | smpp-port=2345 9 | database-type=mysql 10 | database-config=demo 11 | database-enable-queue=1 12 | id=KANNELSMPP 13 | inbound-queue-threads=4 14 | outbound-queue-threads=4 15 | 16 | group=mysql-connection 17 | id=demo 18 | host=localhost 19 | username=demouser 20 | password=demopass 21 | database=kannel_smpp_demo 22 | max-connections=5 23 | 24 | group=bearerbox-connection 25 | id=KSMPPD 26 | host=localhost 27 | port=14001 28 | 29 | group=http-server 30 | port=14010 31 | password=ksmppdpass 32 | 33 | group=smpp-routing 34 | routing-method=1 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /smpp/Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | noinst_LTLIBRARIES = libsmpp.la 3 | libsmpp_la_SOURCES = \ 4 | libsmpp/smpp_bearerbox.c libsmpp/smpp_database_mysql.c libsmpp/smpp_http_client.c libsmpp/smpp_listener.c \ 5 | libsmpp/smpp_plugin.c libsmpp/smpp_queues.c libsmpp/smpp_server.c libsmpp/smpp_uuid.c libsmpp/smpp_database.c \ 6 | libsmpp/smpp_database.c libsmpp/smpp_esme.c libsmpp/smpp_http_server.c libsmpp/smpp_pdu_util.c libsmpp/smpp_queued_pdu.c \ 7 | libsmpp/smpp_route.c libsmpp/smpp_server_cfg.c 8 | libsmpp_la_CPPFLAGS = -fPIC -I ${top_srcdir}/smpp/libsmpp ${libevent_CFLAGS} `gw-config --cflags` 9 | libsmpp_la_LDFLAGS = `gw-config --libs` ${libevent_LIBS} -ldl 10 | 11 | bin_PROGRAMS = ksmppd 12 | ksmppd_SOURCES = ksmppd.c 13 | ksmppd_CPPFLAGS = -I ${top_srcdir}/smpp/libsmpp `gw-config --cflags` 14 | ksmppd_LDFLAGS = `gw-config --libs` ${libevent_LIBS} -ldl 15 | ksmppd_LDADD= libsmpp.la ${libevent_LIBS} 16 | -------------------------------------------------------------------------------- /smpp/ksmppd.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by many 49 | * individuals on behalf of the Kannel Group. For more information on 50 | * the Kannel Group, please see . 51 | * 52 | * 53 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 54 | * 55 | * If you would like to donate to this project you may do so via Bitcoin to 56 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 57 | * 58 | * If you require commercial support for this software you can contact 59 | * 60 | * Kurt Neo 61 | * 62 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 63 | * 64 | */ 65 | 66 | #include 67 | #include 68 | #include 69 | 70 | #include "gwlib/gwlib.h" 71 | #include "gw/heartbeat.h" 72 | #include "libsmpp/smpp_server.h" 73 | #include "libsmpp/smpp_listener.h" 74 | #include 75 | /* Global context for the SMPP Server */ 76 | static SMPPServer *smpp_server_global; 77 | 78 | 79 | static void signal_handler(int signum) { 80 | /* On some implementations (i.e. linuxthreads), signals are delivered 81 | * to all threads. We only want to handle each signal once for the 82 | * entire box, and we let the gwthread wrapper take care of choosing 83 | * one. 84 | */ 85 | if (!gwthread_shouldhandlesignal(signum)) 86 | return; 87 | 88 | switch (signum) { 89 | case SIGINT: 90 | case SIGTERM: 91 | if (!(smpp_server_global->server_status & SMPP_SERVER_STATUS_SHUTDOWN)) { 92 | error(0, "SIGINT received, aborting program..."); 93 | smpp_server_global->server_status |= SMPP_SERVER_STATUS_SHUTDOWN; 94 | smpp_listener_shutdown(smpp_server_global); 95 | gwthread_wakeup_all(); 96 | } 97 | break; 98 | 99 | case SIGUSR2: 100 | warning(0, "SIGUSR2 received, catching and re-opening logs"); 101 | log_reopen(); 102 | alog_reopen(); 103 | break; 104 | case SIGHUP: 105 | warning(0, "SIGHUP received, catching and re-opening logs"); 106 | log_reopen(); 107 | alog_reopen(); 108 | break; 109 | 110 | /* 111 | * It would be more proper to use SIGUSR1 for this, but on some 112 | * platforms that's reserved by the pthread support. 113 | */ 114 | case SIGQUIT: 115 | warning(0, "SIGQUIT ±received, reporting memory usage."); 116 | gw_check_leaks(); 117 | break; 118 | 119 | case SIGSEGV: 120 | panic(0, "SIGSEGV received, exiting immediately"); 121 | break; 122 | } 123 | } 124 | 125 | 126 | static void setup_signal_handlers(void) { 127 | struct sigaction act; 128 | 129 | act.sa_handler = signal_handler; 130 | sigemptyset(&act.sa_mask); 131 | act.sa_flags = 0; 132 | sigaction(SIGINT, &act, NULL); 133 | sigaction(SIGTERM, &act, NULL); 134 | sigaction(SIGQUIT, &act, NULL); 135 | sigaction(SIGHUP, &act, NULL); 136 | sigaction(SIGPIPE, &act, NULL); 137 | sigaction(SIGUSR2, &act, NULL); 138 | // sigaction(SIGSEGV, &act, NULL); 139 | } 140 | 141 | static int check_args(int i, int argc, char **argv) { 142 | return 0; 143 | } 144 | 145 | 146 | /* 147 | * 148 | */int main(int argc, char **argv) 149 | { 150 | int cf_index; 151 | 152 | gwlib_init(); 153 | cf_index = get_and_set_debugs(argc, argv, check_args); 154 | setup_signal_handlers(); 155 | 156 | 157 | SMPPServer *smpp_server = smpp_server_create(); 158 | 159 | smpp_server_global = smpp_server; 160 | 161 | smpp_server->server_status = SMPP_SERVER_STATUS_STARTUP; 162 | 163 | 164 | if (argv[cf_index] == NULL) 165 | smpp_server->config_filename = octstr_create("ksmppd.conf"); 166 | else 167 | smpp_server->config_filename = octstr_create(argv[cf_index]); 168 | 169 | debug("smpp", 0, "Initializing configuration file %s", octstr_get_cstr(smpp_server->config_filename)); 170 | 171 | smpp_server_reconfigure(smpp_server); 172 | 173 | report_versions("ksmppd"); 174 | 175 | info(0, "----------------------------------------------"); 176 | info(0, SMPP_SERVER_NAME " kmppd version %s starting", GITVERSION); 177 | info(0, SMPP_SERVER_NAME " system platform %s ", PLATFORMINFO); 178 | info(0, "----------------------------------------------"); 179 | 180 | smpp_server->server_status = SMPP_SERVER_STATUS_RUNNING; 181 | 182 | smpp_listener_start(smpp_server); // This request will block until stopped 183 | 184 | smpp_server_destroy(smpp_server); 185 | 186 | 187 | log_close_all(); 188 | gwlib_shutdown(); 189 | 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_bearerbox.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_BEARERBOX_H 64 | #define SMPP_BEARERBOX_H 65 | 66 | #define HEARTBEAT_INTERVAL 10 67 | 68 | #ifdef __cplusplus 69 | extern "C" { 70 | #endif 71 | typedef struct { 72 | Msg *msg; 73 | void (*callback)(void *, int); 74 | void *context; 75 | Octstr *id; 76 | } SMPPBearerboxMsg; 77 | 78 | typedef struct { 79 | List *bearerboxes; 80 | gw_prioqueue_t *outbound_queue; 81 | gw_prioqueue_t *inbound_queue; 82 | RWLock *lock; 83 | SMPPServer *smpp_server; 84 | Dict *pending_requeues; 85 | long requeue_thread_id; 86 | } SMPPBearerboxState; 87 | 88 | typedef struct { 89 | Octstr *id; 90 | Octstr *host; 91 | long port; 92 | int ssl; 93 | Connection *connection; 94 | long last_msg; 95 | volatile sig_atomic_t alive; 96 | volatile sig_atomic_t writer_alive; 97 | SMPPBearerboxState *smpp_bearerbox_state; 98 | RWLock *lock; 99 | Dict *open_acks; 100 | RWLock *ack_lock; 101 | } SMPPBearerbox; 102 | 103 | void smpp_bearerbox_init(SMPPServer *smpp_server); 104 | void smpp_bearerbox_shutdown(SMPPServer *smpp_server); 105 | 106 | void smpp_bearerbox_add_message(SMPPServer *smpp_server, Msg *msg, void(*callback)(void*,int), void *context); 107 | SMPPBearerboxMsg *smpp_bearerbox_msg_create(Msg *msg, void(*callback)(void*,int), void *context); 108 | void smpp_bearerbox_msg_destroy(SMPPBearerboxMsg *smpp_bearerbox_msg); 109 | int smpp_bearerbox_acknowledge(SMPPBearerbox *smpp_bearerbox, Octstr *id, ack_status_t status); 110 | 111 | 112 | 113 | #ifdef __cplusplus 114 | } 115 | #endif 116 | 117 | #endif /* SMPP_BEARERBOX_H */ 118 | 119 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_database.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #include "gwlib/gwlib.h" 64 | #include "gw/msg.h" 65 | #include "gw/load.h" 66 | #include "gw/smsc/smpp_pdu.h" 67 | #include "smpp_server.h" 68 | #include "smpp_bearerbox.h" 69 | #include "smpp_esme.h" 70 | #include "smpp_queued_pdu.h" 71 | #include "smpp_database.h" 72 | 73 | SMPPESMEAuthResult *smpp_database_mysql_auth(SMPPServer *smpp_server, Octstr *username, Octstr *mysql); 74 | List *smpp_database_mysql_get_stored(SMPPServer *smpp_server, long sms_type, Octstr *service); 75 | 76 | SMPPDatabaseMsg *smpp_database_msg_create() { 77 | SMPPDatabaseMsg *smpp_database_msg = gw_malloc(sizeof(SMPPDatabaseMsg)); 78 | smpp_database_msg->global_id = 0; 79 | smpp_database_msg->msg = NULL; 80 | smpp_database_msg->wakeup_thread_id = 0; 81 | return smpp_database_msg; 82 | } 83 | 84 | void smpp_database_msg_destroy(SMPPDatabaseMsg *smpp_database_msg) { 85 | msg_destroy(smpp_database_msg->msg); 86 | gw_free(smpp_database_msg); 87 | } 88 | 89 | 90 | SMPPESMEAuthResult *smpp_database_auth(SMPPServer *smpp_server, Octstr *username, Octstr *password) { 91 | SMPPDatabase *smpp_database = smpp_server->database; 92 | return smpp_database->authenticate(smpp_server, username, password); 93 | } 94 | 95 | 96 | SMPPDatabase *smpp_database_create() { 97 | SMPPDatabase *smpp_database = gw_malloc(sizeof(SMPPDatabase)); 98 | smpp_database->authenticate = NULL; 99 | smpp_database->add_message = NULL; 100 | smpp_database->context = NULL; 101 | smpp_database->add_pdu = NULL; 102 | smpp_database->delete = NULL; 103 | smpp_database->get_stored = NULL; 104 | smpp_database->get_stored_pdu = NULL; 105 | smpp_database->pending_msg = NULL; 106 | smpp_database->pending_pdu = NULL; 107 | smpp_database->get_routes = NULL; 108 | smpp_database->deduct_credit = NULL; 109 | smpp_database->get_esmes_with_queued = NULL; 110 | 111 | 112 | return smpp_database; 113 | } 114 | 115 | int smpp_database_add_message(SMPPServer *smpp_server, Msg *msg) { 116 | SMPPDatabase *smpp_database = smpp_server->database; 117 | if(smpp_database->add_message) { 118 | return smpp_database->add_message(smpp_server, msg); 119 | } 120 | return 0; 121 | } 122 | 123 | int smpp_database_add_pdu(SMPPServer *smpp_server, SMPPQueuedPDU *smpp_queued_pdu) { 124 | SMPPDatabase *smpp_database = smpp_server->database; 125 | if(smpp_database->add_pdu) { 126 | return smpp_database->add_pdu(smpp_server, smpp_queued_pdu); 127 | } 128 | return 0; 129 | } 130 | 131 | List *smpp_database_get_routes(SMPPServer *smpp_server, int direction, Octstr *service) { 132 | SMPPDatabase *smpp_database = smpp_server->database; 133 | if(smpp_database->get_routes) { 134 | return smpp_database->get_routes(smpp_server, direction, service); 135 | } 136 | return gwlist_create(); /* Caller will destroy */ 137 | } 138 | 139 | List *smpp_database_get_stored(SMPPServer *smpp_server, long sms_type, Octstr *service, long limit) { 140 | SMPPDatabase *smpp_database = smpp_server->database; 141 | if(smpp_database->get_stored) { 142 | return smpp_database->get_stored(smpp_server, sms_type, service, limit); 143 | } 144 | return gwlist_create(); /* Caller will destroy */ 145 | } 146 | 147 | List *smpp_database_get_stored_pdu(SMPPServer *smpp_server, Octstr *service, long limit) { 148 | SMPPDatabase *smpp_database = smpp_server->database; 149 | if(smpp_database->get_stored_pdu) { 150 | return smpp_database->get_stored_pdu(smpp_server, service, limit); 151 | } 152 | return gwlist_create(); /* Caller will destroy */ 153 | } 154 | 155 | int smpp_database_remove(SMPPServer *smpp_server, unsigned long global_id, int temporary) { 156 | SMPPDatabase *smpp_database = smpp_server->database; 157 | if(smpp_database->delete) { 158 | return smpp_database->delete(smpp_server, global_id, temporary); 159 | } 160 | return 0; 161 | } 162 | 163 | int smpp_database_deduct_credit(SMPPServer *smpp_server, Octstr *service, double cost) { 164 | SMPPDatabase *smpp_database = smpp_server->database; 165 | if(smpp_database->deduct_credit) { 166 | return smpp_database->deduct_credit(smpp_server, service, cost); 167 | } 168 | return 0; 169 | } 170 | 171 | List *smpp_database_get_esmes_with_queued(SMPPServer *smpp_server) { 172 | SMPPDatabase *smpp_database = smpp_server->database; 173 | if(smpp_database->get_esmes_with_queued) { 174 | return smpp_database->get_esmes_with_queued(smpp_server); 175 | } 176 | return gwlist_create(); 177 | } 178 | 179 | void smpp_database_destroy(SMPPDatabase *smpp_database) { 180 | 181 | gw_free(smpp_database); 182 | } 183 | 184 | void *smpp_database_init(SMPPServer *smpp_server) { 185 | if(octstr_case_compare(smpp_server->database_type, octstr_imm("mysql")) == 0) { 186 | debug("smpp.database.init", 0, "Initialize database type to MySQL"); 187 | return smpp_database_mysql_init(smpp_server); 188 | } 189 | 190 | return NULL; 191 | } 192 | 193 | void smpp_database_shutdown(SMPPServer *smpp_server) { 194 | SMPPDatabase *smpp_database = smpp_server->database; 195 | if(smpp_database->shutdown) { 196 | smpp_database->shutdown(smpp_server); 197 | } 198 | 199 | smpp_database_destroy(smpp_database); 200 | } -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_database.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_DATABASE_H 64 | #define SMPP_DATABASE_H 65 | 66 | #define SMPP_DATABASE_BATCH_LIMIT 1000 67 | 68 | #ifdef __cplusplus 69 | extern "C" { 70 | #endif 71 | typedef struct { 72 | Msg *msg; 73 | unsigned long global_id; 74 | SMPPServer *smpp_server; 75 | long wakeup_thread_id; 76 | } SMPPDatabaseMsg; 77 | 78 | 79 | 80 | typedef struct { 81 | SMPPESMEAuthResult *(*authenticate) (void *context, Octstr *system_id, Octstr *password); 82 | int (*add_message)(SMPPServer *context, Msg *msg); 83 | int (*add_pdu)(SMPPServer *context, SMPPQueuedPDU *smpp_queued_pdu); 84 | List *(*get_stored)(SMPPServer *context, long sms_type, Octstr *service, long limit); 85 | List *(*get_stored_pdu)(SMPPServer *context, Octstr *service, long limit); 86 | List *(*get_routes)(SMPPServer *context, int direction, Octstr *service); 87 | int (*deduct_credit)(SMPPServer *context, Octstr *service, double value); 88 | int (*delete)(SMPPServer *context, unsigned long global_id, int temporary); 89 | List *(*get_esmes_with_queued)(SMPPServer *smpp_server); 90 | void (*shutdown)(SMPPServer *context); 91 | void *context; 92 | Dict *pending_pdu; 93 | Dict *pending_msg; 94 | 95 | } SMPPDatabase; 96 | 97 | 98 | SMPPDatabaseMsg *smpp_database_msg_create(); 99 | void smpp_database_msg_destroy(); 100 | 101 | SMPPDatabase *smpp_database_create(); 102 | void smpp_database_destroy(SMPPDatabase *smpp_database); 103 | 104 | 105 | void *smpp_database_init(SMPPServer *smpp_server); 106 | void smpp_database_shutdown(SMPPServer *smpp_server); 107 | 108 | void *smpp_database_mysql_init(SMPPServer *smpp_server); 109 | 110 | SMPPESMEAuthResult *smpp_database_auth(SMPPServer *smpp_server, Octstr *username, Octstr *password); 111 | 112 | int smpp_database_add_message(SMPPServer *smpp_server, Msg *msg); 113 | int smpp_database_add_pdu(SMPPServer *smpp_server, SMPPQueuedPDU *smpp_queued_pdu); 114 | List *smpp_database_get_stored(SMPPServer *smpp_server, long sms_type, Octstr *service, long limit); 115 | List *smpp_database_get_stored_pdu(SMPPServer *smpp_server, Octstr *service, long limit); 116 | List *smpp_database_get_routes(SMPPServer *smpp_server, int direction, Octstr *service); 117 | int smpp_database_deduct_credit(SMPPServer *smpp_server, Octstr *service, double value); 118 | List *smpp_database_get_esmes_with_queued(SMPPServer *smpp_server); 119 | 120 | int smpp_database_remove(SMPPServer *smpp_server, unsigned long global_id, int temporary); 121 | 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif /* SMPP_DATABASE_H */ 128 | 129 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_esme.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_ESME_H 64 | #define SMPP_ESME_H 65 | 66 | #define SMPP_ESME_CLEANUP_INTERVAL 30 67 | #define SMPP_ESME_CLEANUP_QUEUE_DELAY 15 68 | #define SMPP_ESME_MAX_CONSECUTIVE_ERRORS 10 69 | #define SMPP_ESME_WAIT_ACK_TIME 120 70 | #define SMPP_ESME_WAIT_ACK_DISCONNECT 1 71 | #define SMPP_ESME_COMMAND_STATUS_WAIT_ACK_TIMEOUT 0x0400 72 | #define SMPP_ESME_COMMAND_STATUS_QUEUED 0x0401 73 | #define SMPP_ESME_COMMAND_STATUS_QUEUE_ERROR 0x0402 74 | 75 | #define SMPP_ESME_DEFAULT_ENQUIRE_LINK_INTERVAL 180 76 | #define SMPP_ESME_DEFAULT_MAX_OPEN_ACKS 500 77 | 78 | #define SMPP_ESME_UNDEFINED 0 79 | #define SMPP_ESME_TRANSMIT 1 80 | #define SMPP_ESME_RECEIVE 2 81 | 82 | 83 | 84 | #ifdef __cplusplus 85 | extern "C" { 86 | #endif 87 | typedef struct { 88 | Octstr *system_id; 89 | double throughput; 90 | Load *inbound_load; 91 | Load *outbound_load; 92 | List *binds; 93 | List *outbound_routes; 94 | long max_binds; 95 | Counter *inbound_processed; 96 | Counter *outbound_processed; 97 | int enable_prepaid_billing; 98 | Counter *mt_counter; 99 | Counter *mo_counter; 100 | Counter *dlr_counter; 101 | Counter *error_counter; 102 | } SMPPEsmeGlobal; 103 | 104 | 105 | typedef struct { 106 | double throughput; 107 | Octstr *default_smsc; 108 | double default_cost; 109 | 110 | int max_binds; 111 | 112 | Octstr *callback_url; 113 | 114 | int simulate; 115 | unsigned long simulate_deliver_every; 116 | unsigned long simulate_mo_every; 117 | unsigned long simulate_permanent_failure_every; 118 | unsigned long simulate_temporary_failure_every; 119 | 120 | int enable_prepaid_billing; 121 | 122 | Octstr *allowed_ips; 123 | 124 | Octstr *alt_charset; 125 | } SMPPESMEAuthResult; 126 | 127 | typedef struct { 128 | Octstr *system_id; 129 | Octstr *system_type; 130 | Connection *conn; 131 | volatile int authenticated; 132 | volatile int connected; 133 | volatile int pending_disconnect; 134 | 135 | struct event *event_container; 136 | SMPPServer *smpp_server; 137 | long time_connected; 138 | long time_disconnected; 139 | long time_last_pdu; 140 | long time_last_queue_process; 141 | 142 | long enquire_link_interval; 143 | 144 | int bind_type; 145 | int version; 146 | 147 | Load *inbound_load; 148 | Load *outbound_load; 149 | 150 | Counter *inbound_queued; 151 | Counter *outbound_queued; 152 | Counter *pending_routing; 153 | Counter *sequence_number; 154 | 155 | Counter *errors; 156 | RWLock *event_lock; 157 | 158 | long id; 159 | 160 | 161 | Counter *inbound_processed; 162 | Counter *outbound_processed; 163 | 164 | int simulate; 165 | unsigned long simulate_deliver_every; 166 | unsigned long simulate_mo_every; 167 | unsigned long simulate_permanent_failure_every; 168 | unsigned long simulate_temporary_failure_every; 169 | 170 | Octstr *alt_charset; 171 | Octstr *alt_addr_charset; 172 | 173 | Octstr *default_smsc; 174 | double default_cost; 175 | 176 | Dict *open_acks; 177 | RWLock *ack_process_lock; 178 | 179 | Counter *catenated_sms_counter; 180 | 181 | int wait_ack_action; 182 | int wait_ack_time; 183 | 184 | long max_open_acks; 185 | 186 | SMPPEsmeGlobal *smpp_esme_global; 187 | 188 | Octstr *ip; 189 | 190 | long pending_len; 191 | 192 | Counter *mt_counter; 193 | Counter *mo_counter; 194 | Counter *dlr_counter; 195 | Counter *error_counter; 196 | } SMPPEsme; 197 | 198 | typedef struct { 199 | Dict *esmes; 200 | RWLock *lock; 201 | long cleanup_thread_id; 202 | int g_thread_id; 203 | RWLock *cleanup_lock; 204 | List *cleanup_queue; 205 | Load *inbound_load; 206 | Load *outbound_load; 207 | Counter *inbound_processed; 208 | Counter *outbound_processed; 209 | } SMPPEsmeData; 210 | 211 | SMPPESMEAuthResult *smpp_esme_auth_result_create(); 212 | 213 | void smpp_esme_auth_result_destroy(SMPPESMEAuthResult *smpp_esme_auth_result); 214 | 215 | SMPPEsme *smpp_esme_create(); 216 | void smpp_esme_destroy(SMPPEsme *smpp_esme); 217 | 218 | void smpp_esme_init(SMPPServer *smpp_server); 219 | void smpp_esme_shutdown(SMPPServer *smpp_server); 220 | 221 | void smpp_esme_global_add(SMPPServer *smpp_server, SMPPEsme *smpp_esme); 222 | 223 | void smpp_esme_cleanup(SMPPEsme *smpp_esme); 224 | 225 | /* This will just disconnect the connection, no unbind */ 226 | void smpp_esme_disconnect(SMPPEsme *smpp_esme); 227 | 228 | /* Cancel event listeners */ 229 | void smpp_esme_stop_listening(SMPPEsme *smpp_esme); 230 | 231 | void smpp_esme_inbound_load_increase(SMPPEsme *smpp_esme); 232 | void smpp_esme_outbound_load_increase(SMPPEsme *smpp_esme); 233 | SMPPEsme *smpp_esme_find_best_receiver(SMPPServer *smpp_server, Octstr *system_id); 234 | List *smpp_esme_global_get_readers(SMPPServer *smpp_server, int best_only); 235 | List *smpp_esme_global_get_queued(SMPPServer *smpp_server); 236 | 237 | SMPPESMEAuthResult *smpp_esme_auth(SMPPServer *smpp_server, Octstr *system_id, Octstr *password, SMPPEsme *smpp_esme); 238 | 239 | #ifdef __cplusplus 240 | } 241 | #endif 242 | 243 | #endif /* SMPP_ESME_H */ 244 | 245 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_http_client.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_HTTP_CLIENT_H 64 | #define SMPP_HTTP_CLIENT_H 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | #define SMPP_HTTP_HEADER_PREFIX "X-KSMPPD-" 71 | #define HTTP_DEFAULT_MAX_OUTSTANDING 512 72 | 73 | SMPPESMEAuthResult *smpp_http_client_auth(SMPPServer *smpp_server, Octstr *system_id, Octstr *password); 74 | void smpp_http_client_route_init(SMPPServer *smpp_server); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif /* SMPP_HTTP_CLIENT_H */ 81 | 82 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_http_server.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | #include "gwlib/gwlib.h" 63 | #include "smpp_server.h" 64 | #include "smpp_http_server.h" 65 | 66 | typedef struct { 67 | long port; 68 | Octstr *password; 69 | Dict *commands; 70 | long receive_thread; 71 | long start_time; 72 | int ssl; 73 | Octstr *interface; 74 | } SMPPHTTPServer; 75 | 76 | SMPPHTTPCommand *smpp_http_server_command_create() { 77 | SMPPHTTPCommand *smpp_http_command = gw_malloc(sizeof(SMPPHTTPCommand)); 78 | smpp_http_command->callback = NULL; 79 | smpp_http_command->key = NULL; 80 | return smpp_http_command; 81 | } 82 | 83 | void smpp_http_server_command_destroy(SMPPHTTPCommand *smpp_http_command) { 84 | octstr_destroy(smpp_http_command->key); 85 | gw_free(smpp_http_command); 86 | } 87 | 88 | SMPPHTTPServer *smpp_http_server_create() { 89 | SMPPHTTPServer *smpp_http_server = gw_malloc(sizeof(SMPPHTTPServer)); 90 | smpp_http_server->port = 0; 91 | smpp_http_server->password = NULL; 92 | smpp_http_server->commands = dict_create(128, (void(*)(void *))smpp_http_server_command_destroy); 93 | smpp_http_server->receive_thread = 0; 94 | smpp_http_server->interface = NULL; 95 | return smpp_http_server; 96 | } 97 | 98 | void smpp_http_server_destroy(SMPPHTTPServer *smpp_http_server) { 99 | octstr_destroy(smpp_http_server->password); 100 | dict_destroy(smpp_http_server->commands); 101 | gw_free(smpp_http_server); 102 | } 103 | 104 | SMPPHTTPCommandResult *smpp_http_command_result_create() { 105 | SMPPHTTPCommandResult *smpp_http_result = gw_malloc(sizeof(SMPPHTTPCommandResult)); 106 | smpp_http_result->headers = http_create_empty_headers(); 107 | smpp_http_result->result = NULL; 108 | smpp_http_result->status = HTTP_OK; 109 | return smpp_http_result; 110 | } 111 | 112 | void smpp_http_command_result_destroy(SMPPHTTPCommandResult *smpp_http_command_result) { 113 | if(!smpp_http_command_result) { 114 | return; 115 | } 116 | http_destroy_headers(smpp_http_command_result->headers); 117 | octstr_destroy(smpp_http_command_result->result); 118 | gw_free(smpp_http_command_result); 119 | } 120 | 121 | SMPPHTTPCommandResult *smpp_http_command_uptime(SMPPServer *smpp_server, List *cgivars, int content_type) { 122 | SMPPHTTPCommandResult *smpp_http_result = smpp_http_command_result_create(); 123 | SMPPHTTPServer *smpp_http_server = smpp_server->http_server; 124 | long diff = time(NULL) - smpp_http_server->start_time; 125 | 126 | if(content_type == HTTP_CONTENT_TYPE_PLAIN) { 127 | smpp_http_result->result = octstr_format("Uptime %ldd %ldh %ldm %lds\n", diff/3600/24, diff/3600%24, diff/60%60, diff%60); 128 | } else if(content_type == HTTP_CONTENT_TYPE_XML) { 129 | smpp_http_result->result = octstr_format("%ld", diff); 130 | } 131 | 132 | return smpp_http_result; 133 | 134 | } 135 | 136 | SMPPHTTPCommandResult *smpp_http_command_log_level(SMPPServer *smpp_server, List *cgivars, int content_type) { 137 | SMPPHTTPCommandResult *smpp_http_result = smpp_http_command_result_create(); 138 | 139 | Octstr *level = http_cgi_variable(cgivars, "level"); 140 | 141 | int new_loglevel = -1; 142 | 143 | if(octstr_len(level)) { 144 | new_loglevel = atoi(octstr_get_cstr(level)); 145 | } 146 | 147 | if(new_loglevel >= 0) { 148 | log_set_log_level(new_loglevel); 149 | if(content_type == HTTP_CONTENT_TYPE_PLAIN) { 150 | smpp_http_result->result = octstr_format("Log level set to %d\n",new_loglevel); 151 | } else if(content_type == HTTP_CONTENT_TYPE_XML) { 152 | smpp_http_result->result = octstr_format("Log level set to %d\n",new_loglevel); 153 | } 154 | } else { 155 | if(content_type == HTTP_CONTENT_TYPE_PLAIN) { 156 | smpp_http_result->result = octstr_format("Invalid level specified\n"); 157 | } else if(content_type == HTTP_CONTENT_TYPE_XML) { 158 | smpp_http_result->result = octstr_format("Invalid level specified\n"); 159 | } 160 | } 161 | 162 | return smpp_http_result; 163 | } 164 | 165 | void smpp_http_server_request_handler(void *arg) { 166 | SMPPServer *smpp_server = arg; 167 | SMPPHTTPServer *smpp_http_server = smpp_server->http_server; 168 | 169 | HTTPClient *client; 170 | Octstr *ip, *url, *body, *answer; 171 | List *hdrs, *args, *reply_headers; 172 | int status; 173 | 174 | Octstr *password; 175 | long pos; 176 | 177 | Octstr *extension; 178 | int content_type; 179 | List *keys; 180 | Octstr *key; 181 | 182 | SMPPHTTPCommand *smpp_http_command; 183 | SMPPHTTPCommandResult *smpp_http_command_result; 184 | 185 | info(0, "Starting HTTP Server thread on port %ld", smpp_http_server->port); 186 | 187 | for (;;) { 188 | /* reset request wars */ 189 | ip = url = body = answer = NULL; 190 | hdrs = args = NULL; 191 | reply_headers = NULL; 192 | content_type = HTTP_CONTENT_TYPE_PLAIN; 193 | smpp_http_command_result = NULL; 194 | 195 | client = http_accept_request(smpp_http_server->port, &ip, &url, &hdrs, &body, &args); 196 | if(!client) { 197 | break; 198 | } 199 | 200 | debug("smpp.http.server.request.handler", 0, "Received request %s", octstr_get_cstr(url)); 201 | 202 | password = http_cgi_variable(args, "password"); 203 | 204 | if(!octstr_len(password) || (octstr_compare(password, smpp_http_server->password) != -0)) { 205 | status = 403; 206 | answer = octstr_imm("Denied"); 207 | } else { 208 | pos = octstr_rsearch_char(url, '.', (octstr_len(url)-1)); 209 | if(pos != -1) { 210 | extension = octstr_copy(url, pos, octstr_len(url) - pos); 211 | if(octstr_compare(extension, octstr_imm(".xml")) == 0) { 212 | content_type = HTTP_CONTENT_TYPE_XML; 213 | } 214 | octstr_destroy(extension); 215 | octstr_truncate(url, pos); 216 | } 217 | 218 | 219 | smpp_http_command = dict_get(smpp_http_server->commands, url); 220 | 221 | if(smpp_http_command) { 222 | smpp_http_command_result = smpp_http_command->callback(smpp_server, args, content_type); 223 | status = smpp_http_command_result->status; 224 | answer = octstr_duplicate(smpp_http_command_result->result); 225 | reply_headers = smpp_http_command_result->headers; 226 | 227 | } else { 228 | status = 404; 229 | answer = octstr_format("Command '%S' not found, available commands are: \n\n", url); 230 | keys = dict_keys(smpp_http_server->commands); 231 | while((key = gwlist_consume(keys)) != NULL) { 232 | octstr_format_append(answer, "%S\n", key); 233 | octstr_destroy(key); 234 | } 235 | gwlist_destroy(keys, NULL); 236 | } 237 | } 238 | http_send_reply(client, status, reply_headers, answer); 239 | 240 | smpp_http_command_result_destroy(smpp_http_command_result); 241 | 242 | octstr_destroy(answer); 243 | octstr_destroy(ip); 244 | octstr_destroy(url); 245 | http_destroy_headers(hdrs); 246 | octstr_destroy(body); 247 | http_destroy_cgiargs(args); 248 | } 249 | 250 | info(0, "Shutting down HTTP Server thread on port %ld", smpp_http_server->port); 251 | 252 | 253 | } 254 | 255 | 256 | 257 | void smpp_http_server_add_command(SMPPServer *smpp_server, Octstr *key, SMPPHTTPCommandResult *(*callback)(SMPPServer *smpp_server, List *cgivars, int content_type)) { 258 | SMPPHTTPCommand *smpp_http_command = smpp_http_server_command_create(); 259 | smpp_http_command->key = octstr_format("/%S", key); 260 | smpp_http_command->callback = callback; 261 | 262 | SMPPHTTPServer *smpp_http_server = smpp_server->http_server; 263 | dict_put(smpp_http_server->commands, smpp_http_command->key, smpp_http_command); 264 | } 265 | 266 | void smpp_http_server_init(SMPPServer *smpp_server) { 267 | 268 | CfgGroup *grp = cfg_get_single_group(smpp_server->running_configuration, octstr_imm("http-server")); 269 | if(!grp) { 270 | panic(0, "No 'http-server' group configured, cannot continue"); 271 | } 272 | 273 | SMPPHTTPServer *smpp_http_server = smpp_http_server_create(); 274 | smpp_server->http_server = smpp_http_server; 275 | 276 | if(cfg_get_integer(&smpp_http_server->port, grp, octstr_imm("port")) == -1) { 277 | panic(0, "No 'port' specified in 'http-server' group, cannot continue"); 278 | } 279 | 280 | smpp_http_server->password = cfg_get(grp, octstr_imm("password")); 281 | if(!octstr_len(smpp_http_server->password)) { 282 | panic(0, "No 'password' specified in 'http-server' group, cannot continue"); 283 | } 284 | 285 | cfg_get_bool(&smpp_http_server->ssl, grp, octstr_imm("ssl")); 286 | 287 | if(http_open_port_if(smpp_http_server->port, smpp_http_server->ssl, smpp_http_server->interface) == -1) { 288 | panic(0, "Could not start HTTP server on port %ld", smpp_http_server->port); 289 | } 290 | 291 | smpp_http_server_add_command(smpp_server, octstr_imm("uptime"), smpp_http_command_uptime); 292 | smpp_http_server_add_command(smpp_server, octstr_imm("log-level"), smpp_http_command_log_level); 293 | 294 | smpp_http_server->start_time = time(NULL); 295 | 296 | smpp_http_server->receive_thread = gwthread_create(smpp_http_server_request_handler, smpp_server); 297 | 298 | 299 | 300 | } 301 | 302 | void smpp_http_server_shutdown(SMPPServer *smpp_server) { 303 | SMPPHTTPServer *smpp_http_server = smpp_server->http_server; 304 | http_close_port(smpp_http_server->port); 305 | 306 | gwthread_join(smpp_http_server->receive_thread); 307 | 308 | smpp_http_server_destroy(smpp_http_server); 309 | } -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_http_server.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_HTTP_SERVER_H 64 | #define SMPP_HTTP_SERVER_H 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | #define HTTP_CONTENT_TYPE_PLAIN 0 71 | #define HTTP_CONTENT_TYPE_XML 1 72 | 73 | typedef struct { 74 | Octstr *result; 75 | List *headers; 76 | int status; 77 | } SMPPHTTPCommandResult; 78 | 79 | typedef struct { 80 | Octstr *key; 81 | SMPPHTTPCommandResult *(*callback)(SMPPServer *smpp_server, List *cgivars, int content_type); 82 | } SMPPHTTPCommand; 83 | 84 | 85 | void smpp_http_server_init(SMPPServer *smpp_server); 86 | void smpp_http_server_shutdown(SMPPServer *smpp_server); 87 | 88 | SMPPHTTPCommandResult *smpp_http_command_result_create(); 89 | SMPPHTTPCommand *smpp_http_server_command_create(); 90 | void smpp_http_server_add_command(SMPPServer *smpp_server, Octstr *key, SMPPHTTPCommandResult *(*callback)(SMPPServer *smpp_server, List *cgivars, int content_type)); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | #endif /* SMPP_HTTP_SERVER_H */ 97 | 98 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_listener.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #include "gwlib/gwlib.h" 64 | #include "gw/smsc/smpp_pdu.h" 65 | #include "gw/load.h" 66 | #include "gw/msg.h" 67 | #include "smpp_server.h" 68 | #include "smpp_listener.h" 69 | #include "smpp_esme.h" 70 | #include "smpp_bearerbox.h" 71 | #include "smpp_queued_pdu.h" 72 | #include "smpp_queues.h" 73 | #include 74 | #include 75 | 76 | typedef struct { 77 | Octstr *ip; 78 | long time_blocked; 79 | long attempts; 80 | } SMPPBlockedIp; 81 | 82 | SMPPBlockedIp *smpp_blocked_ip_create() { 83 | SMPPBlockedIp *smpp_blocked_ip = gw_malloc(sizeof(SMPPBlockedIp)); 84 | smpp_blocked_ip->ip = NULL; 85 | smpp_blocked_ip->time_blocked = 0; 86 | smpp_blocked_ip->attempts = 0; 87 | 88 | return smpp_blocked_ip; 89 | } 90 | 91 | void smpp_blocked_ip_destroy(SMPPBlockedIp *smpp_blocked_ip) { 92 | octstr_destroy(smpp_blocked_ip->ip); 93 | gw_free(smpp_blocked_ip); 94 | } 95 | 96 | void smpp_listener_auth_failed(SMPPServer *smpp_server, Octstr *ip) { 97 | if (octstr_len(smpp_server->ip_blocklist_exempt_ips) && (octstr_search(smpp_server->ip_blocklist_exempt_ips, ip, 0) > -1)) { 98 | debug("smpp.listener.auth.failed", 0, "IP address %s is exempt from the IP block list", octstr_get_cstr(ip)); 99 | return; 100 | } 101 | gw_rwlock_wrlock(smpp_server->ip_blocklist_lock); 102 | SMPPBlockedIp *smpp_blocked_ip = dict_get(smpp_server->ip_blocklist, ip); 103 | if(smpp_blocked_ip == NULL) { 104 | smpp_blocked_ip = smpp_blocked_ip_create(); 105 | dict_put(smpp_server->ip_blocklist, ip, smpp_blocked_ip); 106 | } 107 | smpp_blocked_ip->attempts++; 108 | smpp_blocked_ip->time_blocked = time(NULL); 109 | debug("smpp.listener.auth.failed", 0, "IP address %s, attempts %ld have failed", octstr_get_cstr(ip), smpp_blocked_ip->attempts); 110 | gw_rwlock_unlock(smpp_server->ip_blocklist_lock); 111 | } 112 | 113 | int smpp_listener_ip_is_blocked(SMPPServer *smpp_server, Octstr *ip) { 114 | int result = 0; 115 | long diff, remaining; 116 | gw_rwlock_wrlock(smpp_server->ip_blocklist_lock); 117 | SMPPBlockedIp *smpp_blocked_ip = dict_get(smpp_server->ip_blocklist, ip); 118 | if(smpp_blocked_ip != NULL) { 119 | diff = time(NULL) - smpp_blocked_ip->time_blocked; 120 | if(diff > smpp_server->ip_blocklist_time) { 121 | debug("smpp.listener.ip.is.blocked", 0, "IP address %s is now unblocked", octstr_get_cstr(ip)); 122 | /* Time has elapsed, can reset (unblock) */ 123 | smpp_blocked_ip->time_blocked = 0; 124 | smpp_blocked_ip->attempts = 0; 125 | } else { 126 | /* Time has not elapsed, how many attempts have they had? */ 127 | if(smpp_blocked_ip->attempts >= smpp_server->ip_blocklist_attempts) { 128 | result = 1; 129 | /* Still blocked */ 130 | remaining = smpp_server->ip_blocklist_time - diff; 131 | debug("smpp.listener.ip.is.blocked", 0, "IP address %s is blocked for another %ld seconds", octstr_get_cstr(ip), remaining); 132 | } 133 | } 134 | } else { 135 | /* Not blocked */ 136 | } 137 | gw_rwlock_unlock(smpp_server->ip_blocklist_lock); 138 | return result; 139 | } 140 | 141 | /* Copied from Kannel smsc_smpp.c */ 142 | static int smpp_listener_read_pdu(SMPPEsme *smpp_esme, long *len, SMPP_PDU **pdu) 143 | { 144 | Connection *conn = smpp_esme->conn; 145 | if(conn == NULL) { 146 | return -1; 147 | } 148 | Octstr *os; 149 | 150 | if (*len == 0) { 151 | *len = smpp_pdu_read_len(conn); 152 | if (*len == -1) { 153 | error(0, "SMPP[%s:%ld]: Client sent garbage, ignored.", 154 | octstr_get_cstr(smpp_esme->system_id), smpp_esme->id); 155 | *len = 0; 156 | return -2; 157 | } else if (*len == 0) { 158 | if (conn_eof(conn) || conn_error(conn)) 159 | return -1; 160 | return 0; 161 | } 162 | } 163 | 164 | os = smpp_pdu_read_data(conn, *len); 165 | if (os == NULL) { 166 | if (conn_eof(conn) || conn_error(conn)) 167 | return -1; 168 | return 0; 169 | } 170 | *len = 0; 171 | 172 | *pdu = smpp_pdu_unpack(smpp_esme->system_id, os); 173 | if (*pdu == NULL) { 174 | error(0, "SMPP[%s]: PDU unpacking failed.", 175 | octstr_get_cstr(smpp_esme->system_id)); 176 | debug("smpp.listener.read.pdu", 0, "SMPP[%s]: Failed PDU follows.", 177 | octstr_get_cstr(smpp_esme->system_id)); 178 | octstr_dump(os, 0); 179 | octstr_destroy(os); 180 | return -2; 181 | } 182 | 183 | octstr_destroy(os); 184 | return 1; 185 | } 186 | 187 | void smpp_listener_event(evutil_socket_t fd, short what, void *arg) 188 | { 189 | SMPPEsme *smpp_esme = arg; 190 | SMPP_PDU *pdu = NULL; 191 | int result; 192 | SMPPQueuedPDU *smpp_queued_pdu; 193 | 194 | if(what & EV_READ) { 195 | debug("smpp.listener.event", 0, "Got a read event for SMPP esme connection %ld %d", smpp_esme->id, smpp_esme->bind_type); 196 | while((result = smpp_listener_read_pdu(smpp_esme, &smpp_esme->pending_len, &pdu)) > 0) { 197 | counter_set(smpp_esme->errors, 0L); 198 | smpp_queued_pdu = smpp_queued_pdu_create(); 199 | smpp_queued_pdu->pdu = pdu; 200 | smpp_queued_pdu->smpp_esme = smpp_esme; 201 | smpp_queues_add_inbound(smpp_queued_pdu); 202 | } 203 | 204 | if(result == 0) { 205 | /* Just no data, who cares*/ 206 | } else { 207 | if(result == -1) { 208 | error(0, "Could not read PDU from %s status was %d", octstr_get_cstr(smpp_esme->system_id), result); 209 | /* This is a connection error we can close this ESME */ 210 | /* Stop listening on this connection, its dead */ 211 | smpp_esme_stop_listening(smpp_esme); 212 | 213 | if(!smpp_esme->authenticated) { /* If there is a pending disconnect operation it means an unbind/rejected bind requested to disconnect, let outbound queue handle */ 214 | /* This bind is not authenticated so will never be cleaned up, lets do it here */ 215 | debug("smpp.listener.event", 0, "Cleaning up disconnected ESME %ld", smpp_esme->id); 216 | smpp_listener_auth_failed(smpp_esme->smpp_server, smpp_esme->ip); 217 | smpp_esme_cleanup(smpp_esme); 218 | } else { 219 | debug("smpp.listener.event", 0, "Allowing background thread to clean up %ld", smpp_esme->id); 220 | } 221 | } else if(result == -2) { 222 | error(0, "Could not read PDU from %s status was %d", octstr_get_cstr(smpp_esme->system_id), result); 223 | counter_increase(smpp_esme->errors); 224 | 225 | if(counter_value(smpp_esme->errors) >= SMPP_ESME_MAX_CONSECUTIVE_ERRORS) { 226 | error(0, "SMPP[%s] max consecutive PDU errors, disconnecting", octstr_get_cstr(smpp_esme->system_id)); 227 | smpp_esme_stop_listening(smpp_esme); 228 | 229 | if(!smpp_esme->authenticated) { 230 | /* This bind is not authenticated so will never be cleaned up, lets do it here */ 231 | smpp_listener_auth_failed(smpp_esme->smpp_server, smpp_esme->ip); 232 | smpp_esme_cleanup(smpp_esme); 233 | } else { 234 | debug("smpp.listener.event", 0, "Allowing background thread to clean up mangled %ld", smpp_esme->id); 235 | } 236 | 237 | } 238 | } 239 | } 240 | } else { 241 | debug("smpp.listener.event", 0, "Got a other event for SMPP esme connection %ld", smpp_esme->id); 242 | } 243 | } 244 | 245 | static void smpp_listener_connection_callback(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *address, int socklen, void *ctx) { 246 | struct event_base *base = evconnlistener_get_base(listener); 247 | 248 | SMPPServer *smpp_server = ctx; 249 | Octstr *ip = NULL; //host_ip(address); 250 | 251 | if (address->sa_family == AF_INET) 252 | { 253 | struct sockaddr_in *sin = (struct sockaddr_in *) address; 254 | ip = host_ip(*sin); 255 | } 256 | 257 | debug("smpp.listener.connection.callback", 0, "Got connection from %s", octstr_get_cstr(ip)); 258 | 259 | if(octstr_len(ip)) { 260 | if(smpp_listener_ip_is_blocked(smpp_server, ip)) { 261 | debug("smpp.listener.connection.callback", 0, "%s is temporarily banned from connecting. Rejecting.", octstr_get_cstr(ip)); 262 | evutil_closesocket(fd); 263 | octstr_destroy(ip); 264 | return; 265 | } 266 | } 267 | 268 | struct event *event_container; 269 | 270 | SMPPEsme *smpp_esme = smpp_esme_create(); 271 | smpp_esme->conn = conn_wrap_fd(fd, smpp_server->enable_ssl); 272 | smpp_esme->connected = 1; 273 | smpp_esme->smpp_server = smpp_server; 274 | smpp_esme->time_connected = time(NULL); 275 | smpp_esme->id = counter_value(smpp_server->esme_counter); 276 | smpp_esme->ip = ip; 277 | smpp_esme->max_open_acks = smpp_server->default_max_open_acks; 278 | 279 | counter_increase(smpp_server->esme_counter); 280 | 281 | event_container = event_new(base, fd, EV_TIMEOUT|EV_READ|EV_PERSIST, smpp_listener_event, 282 | smpp_esme); 283 | 284 | event_add(event_container, NULL); 285 | 286 | smpp_esme->event_container = event_container; 287 | 288 | 289 | } 290 | 291 | static void smpp_listener_accept_error_callback(struct evconnlistener *listener, void *ctx) { 292 | struct event_base *base = evconnlistener_get_base(listener); 293 | int err = EVUTIL_SOCKET_ERROR(); 294 | fprintf(stderr, "Got an error %d (%s) on the listener. " 295 | "Shutting down.\n", err, evutil_socket_error_to_string(err)); 296 | 297 | event_base_loopexit(base, NULL); 298 | } 299 | 300 | void smpp_listener_shutdown(SMPPServer *smpp_server) { 301 | event_base_loopbreak(smpp_server->event_base); 302 | } 303 | 304 | 305 | int smpp_listener_start(SMPPServer *smpp_server) { 306 | struct sockaddr_in sin; 307 | /* Create new event base */ 308 | smpp_server->event_base = event_base_new(); 309 | if (!smpp_server->event_base) { 310 | error(0, "Couldn't open event base"); 311 | return 1; 312 | } 313 | 314 | /* Clear the sockaddr before using it, in case there are extra 315 | * platform-specific fields that can mess us up. */ 316 | memset(&sin, 0, sizeof (sin)); 317 | sin.sin_family = AF_INET; 318 | sin.sin_port = htons(smpp_server->smpp_port); 319 | sin.sin_addr.s_addr = htonl(INADDR_ANY); 320 | 321 | /* Create a new listener */ 322 | info(0, "Starting SMPP server on port %ld", smpp_server->smpp_port); 323 | smpp_server->event_listener = evconnlistener_new_bind(smpp_server->event_base, smpp_listener_connection_callback, smpp_server, 324 | LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, 325 | (struct sockaddr *) &sin, sizeof (sin)); 326 | if (!smpp_server->event_listener) { 327 | panic(0,"Couldn't create listener"); 328 | return 1; 329 | } 330 | 331 | 332 | smpp_server->ip_blocklist = dict_create(512, (void(*)(void *))smpp_blocked_ip_destroy); 333 | 334 | smpp_bearerbox_init(smpp_server); 335 | smpp_esme_init(smpp_server); 336 | smpp_queues_init(smpp_server); 337 | 338 | 339 | 340 | evconnlistener_set_error_cb(smpp_server->event_listener, smpp_listener_accept_error_callback); 341 | 342 | event_base_dispatch(smpp_server->event_base); 343 | 344 | 345 | smpp_queues_shutdown(smpp_server); 346 | smpp_esme_shutdown(smpp_server); 347 | smpp_bearerbox_shutdown(smpp_server); 348 | 349 | dict_destroy(smpp_server->ip_blocklist); 350 | 351 | evconnlistener_free(smpp_server->event_listener); 352 | 353 | event_base_free(smpp_server->event_base); 354 | 355 | return 0; 356 | } 357 | 358 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_listener.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | #ifndef SMPP_LISTENER_H 63 | #define SMPP_LISTENER_H 64 | 65 | #ifdef __cplusplus 66 | extern "C" { 67 | #endif 68 | int smpp_listener_start(SMPPServer *smpp_server); 69 | void smpp_listener_shutdown(SMPPServer *smpp_server); 70 | 71 | void smpp_listener_auth_failed(SMPPServer *smpp_server, Octstr *ip); 72 | int smpp_listener_ip_is_blocked(SMPPServer *smpp_server, Octstr *ip); 73 | 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #endif /* SMPP_LISTENER_H */ 80 | 81 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_pdu_util.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_PDU_UTIL_H 64 | #define SMPP_PDU_UTIL_H 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | Msg *smpp_submit_sm_to_msg(SMPPEsme *smpp_esme, SMPP_PDU *pdu, long *reason); 71 | Msg *smpp_data_sm_to_msg(SMPPEsme *smpp_esme, SMPP_PDU *pdu, long *reason); 72 | Octstr *smpp_pdu_get_system_id_from_dlr_url(Octstr *received_dlr_url); 73 | List *smpp_pdu_msg_to_pdu(SMPPEsme *smpp_esme, Msg *msg); 74 | 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif /* SMPP_PDU_UTIL_H */ 81 | 82 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_plugin.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | /* 64 | * Implementation of dynamic library plugins 65 | * 66 | * Donald Jackson 67 | * 68 | */ 69 | #include 70 | #include "gwlib/gwlib.h" 71 | #include "gw/smsc/smpp_pdu.h" 72 | #include "gw/load.h" 73 | #include "gw/msg.h" 74 | #include "gw/sms.h" 75 | #include "gw/dlr.h" 76 | #include "smpp_server.h" 77 | #include "smpp_bearerbox.h" 78 | #include "smpp_esme.h" 79 | #include "smpp_queued_pdu.h" 80 | #include "smpp_queues.h" 81 | #include "smpp_database.h" 82 | #include "smpp_uuid.h" 83 | #include "smpp_bearerbox.h" 84 | #include "smpp_pdu_util.h" 85 | #include "smpp_route.h" 86 | #include "smpp_http_server.h" 87 | #include "smpp_http_client.h" 88 | #include "smpp_plugin.h" 89 | 90 | SMPPPlugin *smpp_plugin_create() { 91 | SMPPPlugin *smpp_plugin = gw_malloc(sizeof (SMPPPlugin)); 92 | smpp_plugin->authenticate = NULL; 93 | smpp_plugin->context = NULL; 94 | smpp_plugin->init = NULL; 95 | smpp_plugin->reload = NULL; 96 | smpp_plugin->route_message = NULL; 97 | smpp_plugin->shutdown = NULL; 98 | smpp_plugin->args = NULL; 99 | smpp_plugin->id = NULL; 100 | return smpp_plugin; 101 | } 102 | 103 | void smpp_plugin_destroy_real(SMPPPlugin *smpp_plugin) { 104 | octstr_destroy(smpp_plugin->args); 105 | octstr_destroy(smpp_plugin->id); 106 | gw_free(smpp_plugin); 107 | } 108 | 109 | void smpp_plugin_destroy(SMPPPlugin *smpp_plugin) { 110 | if (smpp_plugin->shutdown) { 111 | smpp_plugin->shutdown(smpp_plugin); 112 | } else { 113 | smpp_plugin_destroy_real(smpp_plugin); 114 | } 115 | } 116 | 117 | SMPPPlugin *smpp_plugin_init(SMPPServer *smpp_server, Octstr *id) { 118 | void *lib; 119 | Octstr *path; 120 | Octstr *tmp = NULL; 121 | char *error_str; 122 | 123 | int result = 0; 124 | 125 | 126 | SMPPPlugin *smpp_plugin = dict_get(smpp_server->plugins, id); 127 | if (smpp_plugin == NULL) { 128 | /* Not loaded yet, load now */ 129 | smpp_plugin = smpp_plugin_create(); 130 | smpp_plugin->id = octstr_duplicate(id); 131 | CfgGroup *grp = NULL; 132 | List *grplist; 133 | Octstr *p = NULL; 134 | 135 | grplist = cfg_get_multi_group(smpp_server->running_configuration, octstr_imm("ksmppd-plugin")); 136 | while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) { 137 | p = cfg_get(grp, octstr_imm("id")); 138 | if (p != NULL && octstr_compare(p, id) == 0) { 139 | goto found; 140 | } 141 | if (p != NULL) octstr_destroy(p); 142 | } 143 | panic(0, "Plugin settings for id '%s' are not specified!", 144 | octstr_get_cstr(id)); 145 | 146 | found: 147 | octstr_destroy(p); 148 | gwlist_destroy(grplist, NULL); 149 | 150 | path = cfg_get(grp, octstr_imm("path")); 151 | 152 | if (octstr_len(path)) { 153 | lib = dlopen(octstr_get_cstr(path), RTLD_NOW | RTLD_GLOBAL); 154 | if (!lib) { 155 | error_str = dlerror(); 156 | error(0, "Error opening '%s' for plugin '%s' (%s)", octstr_get_cstr(path), octstr_get_cstr(id), error_str); 157 | goto error; 158 | 159 | } 160 | 161 | error_str = dlerror(); 162 | if (error_str != NULL) { 163 | error(0, "DL returned error %s", error_str); 164 | goto error; 165 | } 166 | 167 | tmp = cfg_get(grp, octstr_imm("init-function")); 168 | if (octstr_len(tmp)) { 169 | smpp_plugin->init = dlsym(lib, octstr_get_cstr(tmp)); 170 | if (!smpp_plugin->init) { 171 | panic(0, "init-function %s unable to load from %s", octstr_get_cstr(tmp), octstr_get_cstr(path)); 172 | } 173 | smpp_plugin->args = cfg_get(grp, octstr_imm("args")); 174 | result = smpp_plugin->init(smpp_plugin); 175 | } else { 176 | result = 1; 177 | } 178 | } 179 | error: 180 | octstr_destroy(path); 181 | octstr_destroy(tmp); 182 | 183 | if (result) { 184 | debug("ksmppd.vsmsc.init", 0, "Adding plugin with id %s and args %s", octstr_get_cstr(smpp_plugin->id), octstr_get_cstr(smpp_plugin->args)); 185 | dict_put(smpp_server->plugins, id, smpp_plugin); 186 | } else { 187 | smpp_plugin_destroy_real(smpp_plugin); 188 | smpp_plugin = NULL; 189 | } 190 | } else { 191 | info(0, "Plugin with id '%s' already initialized", octstr_get_cstr(id)); 192 | } 193 | return smpp_plugin; 194 | } 195 | 196 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_plugin.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | /* 64 | * Implementation of dynamic library plugins 65 | * 66 | * Donald Jackson 67 | * 68 | */ 69 | 70 | #ifndef SMPP_PLUGIN_H 71 | #define SMPP_PLUGIN_H 72 | 73 | #ifdef __cplusplus 74 | extern "C" { 75 | #endif 76 | typedef struct SMPPPlugin SMPPPlugin; 77 | 78 | struct SMPPPlugin { 79 | Octstr *id; 80 | Octstr *args; 81 | SMPPESMEAuthResult *(*authenticate)(SMPPPlugin *smpp_plugin, Octstr *system_id, Octstr *password); 82 | void (*route_message)(SMPPPlugin *smpp_plugin, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context); 83 | int (*init)(SMPPPlugin *smpp_plugin); 84 | void (*reload)(SMPPPlugin *smpp_plugin); 85 | void (*shutdown)(SMPPPlugin *smpp_plugin); 86 | void *context; 87 | }; 88 | 89 | SMPPPlugin *smpp_plugin_init(SMPPServer *smpp_server, Octstr *id); 90 | void smpp_plugin_destroy(SMPPPlugin *smpp_plugin); 91 | void smpp_plugin_destroy_real(SMPPPlugin *smpp_plugin); 92 | 93 | 94 | 95 | 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif /* SMPP_PLUGIN_H */ 102 | 103 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_queued_pdu.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #include "gwlib/gwlib.h" 64 | #include "gw/smsc/smpp_pdu.h" 65 | #include "gw/msg.h" 66 | #include "gw/load.h" 67 | #include "smpp_server.h" 68 | #include "smpp_esme.h" 69 | #include "smpp_bearerbox.h" 70 | #include "smpp_queued_pdu.h" 71 | 72 | 73 | 74 | 75 | SMPPQueuedPDU *smpp_queued_pdu_create() { 76 | SMPPQueuedPDU *smpp_queued_pdu = gw_malloc(sizeof(SMPPQueuedPDU)); 77 | smpp_queued_pdu->pdu = NULL; 78 | smpp_queued_pdu->smpp_esme = NULL; 79 | smpp_queued_pdu->priority = 0; 80 | smpp_queued_pdu->disconnect = 0; 81 | smpp_queued_pdu->id = NULL; 82 | smpp_queued_pdu->system_id = NULL; 83 | smpp_queued_pdu->callback = NULL; 84 | smpp_queued_pdu->context = NULL; 85 | smpp_queued_pdu->bearerbox = NULL; 86 | smpp_queued_pdu->bearerbox_id = NULL; 87 | smpp_queued_pdu->smpp_server = NULL; 88 | smpp_queued_pdu->time_sent = 0; 89 | smpp_queued_pdu->sequence = 0; 90 | smpp_queued_pdu->global_id = 0; 91 | return smpp_queued_pdu; 92 | } 93 | 94 | SMPPQueuedPDU *smpp_queued_pdu_create_quick(SMPPEsme *smpp_esme, unsigned long type, unsigned long seq_no) { 95 | SMPPQueuedPDU *smpp_queued_pdu = smpp_queued_pdu_create(); 96 | smpp_queued_pdu->smpp_esme = smpp_esme; 97 | smpp_queued_pdu->pdu = smpp_pdu_create(type, seq_no); 98 | smpp_queued_pdu->id = NULL; 99 | smpp_queued_pdu->system_id = octstr_duplicate(smpp_esme->system_id); 100 | smpp_queued_pdu->smpp_server = smpp_esme->smpp_server; 101 | return smpp_queued_pdu; 102 | } 103 | 104 | void smpp_queued_pdu_destroy(SMPPQueuedPDU *smpp_queued_pdu) { 105 | smpp_pdu_destroy(smpp_queued_pdu->pdu); 106 | octstr_destroy(smpp_queued_pdu->id); 107 | octstr_destroy(smpp_queued_pdu->system_id); 108 | octstr_destroy(smpp_queued_pdu->bearerbox_id); 109 | gw_free(smpp_queued_pdu); 110 | } -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_queued_pdu.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_QUEUED_PDU_H 64 | #define SMPP_QUEUED_PDU_H 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | #define SMPP_QUEUED_PDU_DESTROYED 0x04FE 71 | 72 | typedef struct { 73 | SMPP_PDU *pdu; 74 | SMPPEsme *smpp_esme; 75 | long priority; 76 | int disconnect; /* If this flag is set the connection will be free'd/disconnected after its sent */ 77 | Octstr *id; 78 | Octstr *system_id; /* If the esme is null, this is used to route deliver_sm/data_sm return PDU's */ 79 | void (*callback)(void *context, long status); 80 | void *context; 81 | long time_sent; 82 | SMPPBearerbox *bearerbox; 83 | Octstr *bearerbox_id; 84 | SMPPServer *smpp_server; 85 | long sequence; 86 | unsigned long global_id; 87 | Msg *msg; 88 | } SMPPQueuedPDU; 89 | 90 | SMPPQueuedPDU *smpp_queued_pdu_create(); 91 | SMPPQueuedPDU *smpp_queued_pdu_create_quick(SMPPEsme *smpp_esme, unsigned long type, unsigned long seq_no); 92 | void smpp_queued_pdu_destroy(SMPPQueuedPDU *smpp_queued_pdu); 93 | List *smpp_pdu_msg_to_pdu(SMPPEsme *smpp_esme, Msg *msg); 94 | 95 | 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif /* SMPP_QUEUED_PDU_H */ 102 | 103 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_queues.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | #ifndef SMPP_QUEUE_H 63 | #define SMPP_QUEUE_H 64 | 65 | #ifdef __cplusplus 66 | extern "C" { 67 | #endif 68 | void smpp_queues_callback_deliver_sm_resp(void *context, long status); 69 | 70 | int smpp_queues_add_outbound(SMPPQueuedPDU *smpp_queued_pdu); 71 | int smpp_queues_add_inbound(SMPPQueuedPDU *smpp_queued_pdu); 72 | 73 | void smpp_queues_send_enquire_link(SMPPEsme *smpp_esme); 74 | 75 | int smpp_queues_pdu_compare(const void *a, const void *b); 76 | void smpp_queues_init(SMPPServer *smpp_server); 77 | void smpp_queues_shutdown(SMPPServer *smpp_server); 78 | 79 | 80 | 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | #endif /* SMPP_QUEUE_H */ 87 | 88 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_route.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #include "gwlib/gwlib.h" 64 | #include "gw/smsc/smpp_pdu.h" 65 | #include "gw/load.h" 66 | #include "gw/msg.h" 67 | #include "gw/sms.h" 68 | #include "gw/dlr.h" 69 | #include "smpp_server.h" 70 | #include "smpp_bearerbox.h" 71 | #include "smpp_esme.h" 72 | #include "smpp_queued_pdu.h" 73 | #include "smpp_queues.h" 74 | #include "smpp_database.h" 75 | #include "smpp_uuid.h" 76 | #include "smpp_bearerbox.h" 77 | #include "smpp_pdu_util.h" 78 | #include "smpp_route.h" 79 | #include "smpp_http_server.h" 80 | #include "smpp_http_client.h" 81 | #include "smpp_plugin.h" 82 | 83 | SMPPRouteStatus *smpp_route_status_create(Msg *msg) { 84 | SMPPRouteStatus *smpp_route_status = gw_malloc(sizeof(SMPPRouteStatus)); 85 | 86 | if(msg && (msg_type(msg) == sms) && (msg->sms.msgdata != NULL)) { 87 | List *parts = sms_split(msg, NULL, NULL, NULL, NULL, 1, 1, 255, MAX_SMS_OCTETS); 88 | smpp_route_status->parts = gwlist_len(parts); 89 | gwlist_destroy(parts, (void(*)(void *))msg_destroy); 90 | } else { 91 | smpp_route_status->parts = 1; 92 | } 93 | smpp_route_status->status = SMPP_ESME_RINVDSTADR; 94 | smpp_route_status->cost = 0; 95 | 96 | return smpp_route_status; 97 | } 98 | 99 | void smpp_route_status_destroy(SMPPRouteStatus *smpp_route_status) { 100 | gw_free(smpp_route_status); 101 | } 102 | 103 | SMPPRoute *smpp_route_create() { 104 | SMPPRoute *smpp_route = gw_malloc(sizeof(SMPPRoute)); 105 | smpp_route->cost = 0; 106 | smpp_route->direction = SMPP_ROUTE_DIRECTION_UNKNOWN; 107 | smpp_route->regex = NULL; 108 | smpp_route->system_id = NULL; 109 | smpp_route->smsc_id = NULL; 110 | smpp_route->source_regex = NULL; 111 | return smpp_route; 112 | } 113 | 114 | void smpp_route_destroy(SMPPRoute *smpp_route) { 115 | octstr_destroy(smpp_route->system_id); 116 | octstr_destroy(smpp_route->smsc_id); 117 | gw_regex_destroy(smpp_route->regex); 118 | gw_regex_destroy(smpp_route->source_regex); 119 | gw_free(smpp_route); 120 | } 121 | 122 | SMPPOutboundRoutes *smpp_outbound_routes_create() { 123 | SMPPOutboundRoutes *smpp_outbound_routes = gw_malloc(sizeof(SMPPOutboundRoutes)); 124 | smpp_outbound_routes->system_id = NULL; 125 | smpp_outbound_routes->routes = NULL; 126 | smpp_outbound_routes->lock = gw_rwlock_create(); 127 | return smpp_outbound_routes; 128 | } 129 | 130 | void smpp_outbound_routes_destroy(List *smpp_outbound_routes) { 131 | gwlist_destroy(smpp_outbound_routes, (void(*)(void *))smpp_route_destroy); 132 | } 133 | 134 | void smpp_route_shutdown_database(SMPPServer *smpp_server) { 135 | 136 | } 137 | 138 | void smpp_route_rebuild_database(SMPPServer *smpp_server) { 139 | info(0, "Rebuilding database routes"); 140 | SMPPRouting *smpp_routing = smpp_server->routing; 141 | List *inbound_routes = smpp_database_get_routes(smpp_server, SMPP_ROUTE_DIRECTION_INBOUND, NULL); /* Only inbound are built, outbound are built when ESME's connect */ 142 | 143 | List *old_inbound; 144 | Dict *old_outbound; 145 | 146 | gw_rwlock_wrlock(smpp_routing->lock); 147 | old_inbound = smpp_routing->inbound_routes; 148 | old_outbound = smpp_routing->outbound_routes; 149 | smpp_routing->inbound_routes = inbound_routes; 150 | smpp_routing->outbound_routes = dict_create(1024, (void(*)(void *))smpp_outbound_routes_destroy); /* Just reset, they will repopulate on their own */ 151 | 152 | gw_rwlock_unlock(smpp_routing->lock); 153 | 154 | gwlist_destroy(old_inbound, (void(*)(void *))smpp_route_destroy); 155 | dict_destroy(old_outbound); 156 | } 157 | 158 | void smpp_route_message_database(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context) { 159 | SMPPRouting *smpp_routing = smpp_server->routing; 160 | List *routes; 161 | 162 | long i, num_routes; 163 | 164 | int found = 0; 165 | SMPPRoute *route; 166 | 167 | SMPPRouteStatus *smpp_route_status = smpp_route_status_create(msg); 168 | 169 | gw_rwlock_rdlock(smpp_routing->lock); 170 | if(msg_type(msg) == sms) { /* we can only route sms's */ 171 | if((direction == SMPP_ROUTE_DIRECTION_OUTBOUND) && octstr_len(system_id)) { 172 | /* Look for our ESME routes */ 173 | gw_rwlock_wrlock(smpp_routing->outbound_lock); 174 | routes = dict_get(smpp_routing->outbound_routes, system_id); 175 | if(!routes) { 176 | routes = smpp_database_get_routes(smpp_server, direction, system_id); 177 | dict_put(smpp_routing->outbound_routes, system_id, routes); 178 | } 179 | gw_rwlock_unlock(smpp_routing->outbound_lock); 180 | 181 | num_routes = gwlist_len(routes); 182 | for(i=0;iregex, msg->sms.receiver); 185 | 186 | if(found) { 187 | if(route->source_regex) { 188 | found = 0; 189 | found = gw_regex_match_pre(route->source_regex, msg->sms.sender); 190 | if(found) { 191 | break; 192 | } else { 193 | debug("smpp.route.message.database", 0, "Found matching outbound route for %s but declined sender %s", octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(msg->sms.sender)); 194 | smpp_route_status->status = SMPP_ESME_RINVSRCADR; 195 | } 196 | } else { 197 | break; 198 | } 199 | } 200 | } 201 | 202 | if(found) { 203 | smpp_route_status->status = SMPP_ESME_ROK; 204 | smpp_route_status->cost = route->cost; 205 | octstr_destroy(msg->sms.smsc_id); 206 | msg->sms.smsc_id = octstr_duplicate(route->smsc_id); 207 | debug("smpp.route.message.database", 0, "SMPP[%s] Found outbound route from %s for %s towards %s", octstr_get_cstr(system_id), octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(msg->sms.smsc_id)); 208 | callback(context, smpp_route_status); 209 | } else { 210 | callback(context, smpp_route_status); 211 | } 212 | } else if((direction == SMPP_ROUTE_DIRECTION_INBOUND) && octstr_len(smsc_id)) { 213 | routes = smpp_routing->inbound_routes; 214 | num_routes = gwlist_len(routes); 215 | for(i=0;ismsc_id)) { 221 | if(octstr_case_compare(route->smsc_id, smsc_id) != 0) { 222 | debug("smpp.route.message.database", 0, "Cannot route messages from SMSC %s to route with SMSC %s", octstr_get_cstr(smsc_id), octstr_get_cstr(route->smsc_id)); 223 | continue; 224 | } 225 | } 226 | 227 | found = gw_regex_match_pre(route->regex, msg->sms.receiver); 228 | 229 | if(found) { 230 | if(route->source_regex) { 231 | found = 0; 232 | found = gw_regex_match_pre(route->source_regex, msg->sms.sender); 233 | if(found) { 234 | break; 235 | } else { 236 | debug("smpp.route.message.database", 0, "Found matching inbound route for %s but declined sender %s", octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(msg->sms.sender)); 237 | smpp_route_status->status = SMPP_ESME_RINVSRCADR; 238 | } 239 | } else { 240 | break; 241 | } 242 | } 243 | } 244 | 245 | if(found) { 246 | smpp_route_status->status = SMPP_ESME_ROK; 247 | smpp_route_status->cost = route->cost; 248 | octstr_destroy(msg->sms.service); 249 | msg->sms.service = octstr_duplicate(route->system_id); 250 | debug("smpp.route.message.database", 0, "SMPP[%s] Found inbound route from %s for %s from %s", octstr_get_cstr(route->system_id), octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(smsc_id)); 251 | callback(context, smpp_route_status); 252 | } else { 253 | callback(context, smpp_route_status); 254 | } 255 | } else { 256 | callback(context, smpp_route_status); 257 | } 258 | } else { 259 | callback(context, smpp_route_status); 260 | } 261 | 262 | gw_rwlock_unlock(smpp_routing->lock); 263 | } 264 | 265 | void smpp_route_message_plugin(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context) { 266 | SMPPPlugin *smpp_plugin = smpp_server->plugin_route; 267 | if(smpp_plugin) { 268 | if(smpp_plugin->route_message) { 269 | smpp_plugin->route_message(smpp_plugin, direction, smsc_id, system_id, msg, callback, context); 270 | return; 271 | } 272 | } 273 | SMPPRouteStatus *smpp_route_status = smpp_route_status_create(msg); 274 | callback(context, smpp_route_status); 275 | } 276 | 277 | void smpp_route_message(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context) { 278 | SMPPRouting *smpp_routing = smpp_server->routing; 279 | if(smpp_routing->route_message) { 280 | smpp_routing->route_message(smpp_server, direction, smsc_id, system_id, msg, callback, context); 281 | } 282 | } 283 | 284 | void smpp_route_rebuild(SMPPServer *smpp_server) { 285 | SMPPRouting *smpp_routing = smpp_server->routing; 286 | if(smpp_routing->reload) { 287 | smpp_routing->reload(smpp_server); 288 | } 289 | } 290 | 291 | void smpp_route_init_method(SMPPServer *smpp_server) { 292 | SMPPRouting *smpp_routing = smpp_server->routing; 293 | if(smpp_routing->init) { 294 | smpp_routing->init(smpp_server); 295 | } 296 | } 297 | 298 | SMPPHTTPCommandResult *smpp_route_rebuild_command(SMPPServer *smpp_server, List *cgivars, int content_type) { 299 | smpp_route_rebuild(smpp_server); 300 | 301 | SMPPHTTPCommandResult *smpp_http_command_result = smpp_http_command_result_create(); 302 | 303 | if(content_type == HTTP_CONTENT_TYPE_PLAIN) { 304 | smpp_http_command_result->result = octstr_create("Routes updated"); 305 | } else if(content_type == HTTP_CONTENT_TYPE_XML) { 306 | smpp_http_command_result->result = octstr_create("Routes updated"); 307 | } 308 | 309 | return smpp_http_command_result; 310 | } 311 | 312 | 313 | void smpp_route_init(SMPPServer *smpp_server) { 314 | SMPPRouting *smpp_routing = gw_malloc(sizeof(SMPPRouting)); 315 | smpp_server->routing = smpp_routing; 316 | smpp_routing->lock = gw_rwlock_create(); 317 | smpp_routing->inbound_routes = NULL; 318 | smpp_routing->outbound_routes = NULL; 319 | smpp_routing->reload = NULL; 320 | smpp_routing->route_message = NULL; 321 | smpp_routing->shutdown = NULL; 322 | smpp_routing->init = NULL; 323 | smpp_routing->outbound_lock = gw_rwlock_create(); 324 | smpp_routing->initialized = 0; 325 | 326 | 327 | CfgGroup *grp = cfg_get_single_group(smpp_server->running_configuration, octstr_imm("smpp-routing")); 328 | long tmp; 329 | Octstr *tmp_str; 330 | 331 | if(!grp) { 332 | warning(0, "No 'smpp-routing' group specified, using defaults (database)"); 333 | tmp = SMPP_ROUTING_DEFAULT_METHOD; 334 | } else { 335 | if(cfg_get_integer(&tmp, grp, octstr_imm("routing-method")) == -1) { 336 | /* Unable to read an integer */ 337 | tmp_str = cfg_get(grp, octstr_imm("routing-method")); 338 | if(!octstr_len(tmp_str)) { 339 | tmp = SMPP_ROUTING_DEFAULT_METHOD; 340 | } else { 341 | /* Read a non-integer string */ 342 | if(octstr_case_compare(tmp_str, octstr_imm("database")) == 0) { 343 | tmp = SMPP_ROUTING_METHOD_DATABASE; 344 | } else if(octstr_case_compare(tmp_str, octstr_imm("http")) == 0) { 345 | tmp = SMPP_ROUTING_METHOD_HTTP; 346 | } else if(octstr_case_compare(tmp_str, octstr_imm("plugin")) == 0) { 347 | tmp = SMPP_ROUTING_METHOD_PLUGIN; 348 | octstr_destroy(tmp_str); 349 | tmp_str = cfg_get(grp, octstr_imm("plugin-id")); 350 | if(!octstr_len(tmp_str)) { 351 | panic(0, "Requested plugin routing but no id specified, cannot continue"); 352 | } else { 353 | smpp_server->plugin_route = smpp_plugin_init(smpp_server, tmp_str); 354 | if(!smpp_server->plugin_route || !smpp_server->plugin_route->route_message) { 355 | panic(0, "Plugin based routing initialization failed."); 356 | } else { 357 | info(0, "Plugin based routing initialization OK."); 358 | smpp_routing->route_message = smpp_route_message_plugin; 359 | } 360 | } 361 | } else { 362 | panic(0, "Unknown routing method '%s'", octstr_get_cstr(tmp_str)); 363 | } 364 | } 365 | octstr_destroy(tmp_str); 366 | } 367 | } 368 | 369 | if(tmp == SMPP_ROUTING_METHOD_DATABASE) { 370 | info(0, "Initializing database based routing"); 371 | smpp_routing->reload = smpp_route_rebuild_database; 372 | smpp_routing->route_message = smpp_route_message_database; 373 | smpp_routing->shutdown = smpp_route_shutdown_database; 374 | } else if(tmp == SMPP_ROUTING_METHOD_HTTP) { 375 | smpp_routing->init = smpp_http_client_route_init; 376 | } else if(tmp == SMPP_ROUTING_METHOD_PLUGIN) { 377 | info(0, "Initializing plugin based routing"); 378 | } 379 | 380 | 381 | 382 | smpp_route_init_method(smpp_server); 383 | 384 | smpp_route_rebuild(smpp_server); 385 | 386 | smpp_http_server_add_command(smpp_server, octstr_imm("rebuild-routes"), smpp_route_rebuild_command); 387 | } 388 | void smpp_route_shutdown(SMPPServer *smpp_server) { 389 | SMPPRouting *smpp_routing = smpp_server->routing; 390 | if(smpp_routing->shutdown) { 391 | smpp_routing->shutdown(smpp_server); 392 | } 393 | 394 | dict_destroy(smpp_routing->outbound_routes); 395 | gwlist_destroy(smpp_routing->inbound_routes, (void(*)(void *))smpp_route_destroy); 396 | gw_rwlock_destroy(smpp_routing->lock); 397 | gw_rwlock_destroy(smpp_routing->outbound_lock); 398 | 399 | gw_free(smpp_routing); 400 | } 401 | 402 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_route.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | #ifndef SMPP_ROUTE_H 63 | #define SMPP_ROUTE_H 64 | 65 | #include "gwlib/gw-regex.h" 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | 72 | #define SMPP_ROUTE_DIRECTION_UNKNOWN 0 73 | #define SMPP_ROUTE_DIRECTION_OUTBOUND 1 74 | #define SMPP_ROUTE_DIRECTION_INBOUND 2 75 | 76 | #define SMPP_ROUTING_METHOD_DATABASE 1 77 | #define SMPP_ROUTING_METHOD_HTTP 2 78 | #define SMPP_ROUTING_METHOD_PLUGIN 4 79 | #define SMPP_ROUTING_DEFAULT_METHOD SMPP_ROUTING_METHOD_DATABASE 80 | 81 | typedef struct { 82 | long parts; 83 | double cost; 84 | int status; 85 | } SMPPRouteStatus; 86 | 87 | typedef struct { 88 | regex_t *regex; 89 | Octstr *system_id; 90 | Octstr *smsc_id; 91 | double cost; 92 | int direction; 93 | void *context; 94 | regex_t *source_regex; 95 | } SMPPRoute; 96 | 97 | typedef struct { 98 | Octstr *system_id; 99 | List *routes; 100 | RWLock *lock; 101 | } SMPPOutboundRoutes; 102 | 103 | typedef struct { 104 | Dict *outbound_routes; 105 | List *inbound_routes; 106 | void (*route_message)(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context); 107 | void (*reload)(SMPPServer *smpp_server); 108 | void (*shutdown)(SMPPServer *smpp_server); 109 | void (*init)(SMPPServer *smpp_server); 110 | RWLock *lock; 111 | RWLock *outbound_lock; 112 | int initialized; 113 | Octstr *http_routing_url; 114 | void *context; 115 | } SMPPRouting; 116 | 117 | 118 | void smpp_route_message_database(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context); 119 | 120 | void smpp_route_init(SMPPServer *smpp_server); 121 | void smpp_route_shutdown(SMPPServer *smpp_server); 122 | void smpp_route_rebuild(SMPPServer *smpp_server); 123 | void smpp_route_message(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, SMPPRouteStatus *smpp_route_status), void *context); 124 | 125 | SMPPRoute *smpp_route_create(); 126 | void smpp_route_destroy(SMPPRoute *smpp_route); 127 | 128 | SMPPRouteStatus *smpp_route_status_create(Msg *msg); 129 | void smpp_route_status_destroy(SMPPRouteStatus *smpp_route_status); 130 | 131 | 132 | 133 | #ifdef __cplusplus 134 | } 135 | #endif 136 | 137 | #endif /* SMPP_ROUTE_H */ 138 | 139 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_server.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | #include "gwlib/gwlib.h" 63 | #include "gw/smsc/smpp_pdu.h" 64 | #include "gw/load.h" 65 | #include "gw/msg.h" 66 | #include "smpp_server.h" 67 | #include "smpp_server_cfg.h" 68 | #include "smpp_esme.h" 69 | #include "smpp_bearerbox.h" 70 | #include "smpp_queued_pdu.h" 71 | #include "smpp_queues.h" 72 | #include "smpp_database.h" 73 | #include "gw/msg.h" 74 | #include "smpp_route.h" 75 | #include "smpp_http_server.h" 76 | #include "smpp_plugin.h" 77 | 78 | SMPPServer *smpp_server_create() { 79 | SMPPServer *smpp_server = gw_malloc(sizeof (SMPPServer)); 80 | smpp_server->bearerbox_inbound_queue = gwlist_create(); 81 | smpp_server->bearerbox_outbound_queue = gwlist_create(); 82 | smpp_server->config_lock = gw_rwlock_create(); 83 | smpp_server->configured = 0; 84 | smpp_server->server_id = NULL; 85 | smpp_server->config_filename = NULL; 86 | smpp_server->database_type = NULL; 87 | smpp_server->database_config = NULL; 88 | smpp_server->database_pdu_table = NULL; 89 | smpp_server->database_route_table = NULL; 90 | smpp_server->database_store_table = NULL; 91 | smpp_server->database_user_table = NULL; 92 | smpp_server->database_version_table = NULL; 93 | 94 | smpp_server->running_configuration = NULL; 95 | smpp_server->inbound_queue = NULL; 96 | smpp_server->outbound_queue = NULL; 97 | smpp_server->simulation_queue = NULL; 98 | smpp_server->esme_counter = counter_create(); 99 | smpp_server->bearerbox = NULL; 100 | smpp_server->database_pdu_table = NULL; 101 | smpp_server->auth_url = NULL; 102 | smpp_server->plugin_auth = NULL; 103 | smpp_server->plugin_route = NULL; 104 | smpp_server->plugins = dict_create(8, (void(*)(void *))smpp_plugin_destroy); 105 | smpp_server->ip_blocklist = NULL; 106 | smpp_server->ip_blocklist_lock = gw_rwlock_create(); 107 | smpp_server->ip_blocklist_time = 0; 108 | smpp_server->ip_blocklist_exempt_ips = NULL; 109 | 110 | smpp_server->default_max_open_acks = SMPP_ESME_DEFAULT_MAX_OPEN_ACKS; 111 | smpp_server->wait_ack_action = SMPP_WAITACK_DISCONNECT; 112 | 113 | return smpp_server; 114 | } 115 | 116 | void smpp_server_destroy(SMPPServer *smpp_server) { 117 | smpp_http_server_shutdown(smpp_server); 118 | smpp_database_shutdown(smpp_server); 119 | smpp_route_shutdown(smpp_server); 120 | dict_destroy(smpp_server->plugins); 121 | octstr_destroy(smpp_server->server_id); 122 | gwlist_destroy(smpp_server->bearerbox_inbound_queue, (void(*)(void *))msg_destroy); 123 | gwlist_destroy(smpp_server->bearerbox_outbound_queue, (void(*)(void *))msg_destroy); 124 | gw_rwlock_destroy(smpp_server->config_lock); 125 | octstr_destroy(smpp_server->database_type); 126 | octstr_destroy(smpp_server->database_config); 127 | octstr_destroy(smpp_server->database_pdu_table); 128 | octstr_destroy(smpp_server->database_route_table); 129 | octstr_destroy(smpp_server->database_store_table); 130 | octstr_destroy(smpp_server->database_user_table); 131 | octstr_destroy(smpp_server->database_version_table); 132 | octstr_destroy(smpp_server->config_filename); 133 | counter_destroy(smpp_server->esme_counter); 134 | counter_destroy(smpp_server->running_threads); 135 | octstr_destroy(smpp_server->auth_url); 136 | gw_rwlock_destroy(smpp_server->ip_blocklist_lock); 137 | octstr_destroy(smpp_server->ip_blocklist_exempt_ips); 138 | 139 | cfg_destroy(smpp_server->running_configuration); 140 | 141 | 142 | gw_free(smpp_server); 143 | } 144 | 145 | int smpp_server_reconfigure(SMPPServer *smpp_server) { 146 | int status = 0; 147 | long tmp; 148 | gw_rwlock_wrlock(smpp_server->config_lock); 149 | Cfg *cfg = cfg_create(smpp_server->config_filename); 150 | CfgGroup *grp; 151 | Octstr *tmp_str; 152 | Octstr *plugin_id; 153 | 154 | if(!smpp_server->configured) { 155 | debug("smpp", 0, "Adding configuration hooks"); 156 | cfg_add_hooks(smpp_server_cfg_is_allowed_in_group, smpp_server_cfg_is_single_group); 157 | } 158 | 159 | 160 | if (cfg_read(cfg) == -1) { 161 | status = -1; 162 | if (!smpp_server->configured) { 163 | panic(0, "Unable to read configuration file %s", octstr_get_cstr(smpp_server->config_filename)); 164 | } else { 165 | error(0, "Unable to refresh configuration file %s", octstr_get_cstr(smpp_server->config_filename)); 166 | } 167 | } else { 168 | grp = cfg_get_single_group(cfg, octstr_imm("ksmppd")); 169 | 170 | if (grp) { 171 | if(smpp_server->configured) { 172 | cfg_destroy(smpp_server->running_configuration); 173 | } 174 | smpp_server->running_configuration = cfg; 175 | if(!smpp_server->configured) { 176 | debug("smpp", 0, "Running one time (initial) configuration"); 177 | smpp_pdu_init(cfg); 178 | 179 | Octstr *logfile = cfg_get(grp, octstr_imm("log-file")); 180 | cfg_get_integer(&tmp, grp, octstr_imm("log-level")); 181 | 182 | if (logfile != NULL) { 183 | info(0, "Starting to log to file %s level %ld", octstr_get_cstr(logfile), tmp); 184 | log_open(octstr_get_cstr(logfile), tmp, GW_NON_EXCL); 185 | octstr_destroy(logfile); 186 | } 187 | 188 | if(cfg_get_integer(&smpp_server->smpp_port, grp, octstr_imm("smpp-port")) == -1) { 189 | smpp_server->smpp_port = 2345; 190 | } 191 | 192 | 193 | 194 | smpp_server->server_id = cfg_get(grp, octstr_imm("id")); 195 | 196 | smpp_server->running_threads = counter_create(); 197 | 198 | smpp_server->enable_ssl = 0; 199 | 200 | if(cfg_get_integer(&smpp_server->num_inbound_queue_threads, grp, octstr_imm("inbound-queue-threads")) == -1) { 201 | smpp_server->num_inbound_queue_threads = 1; 202 | } 203 | 204 | if(cfg_get_integer(&smpp_server->num_outbound_queue_threads, grp, octstr_imm("outbound-queue-threads")) == -1) { 205 | smpp_server->num_outbound_queue_threads = 1; 206 | } 207 | 208 | if(cfg_get_integer(&smpp_server->ip_blocklist_time, grp, octstr_imm("ip-blocklist-time")) == -1) { 209 | smpp_server->ip_blocklist_time = 300; 210 | } 211 | 212 | if(cfg_get_integer(&smpp_server->ip_blocklist_attempts, grp, octstr_imm("ip-blocklist-attempts")) == -1) { 213 | smpp_server->ip_blocklist_attempts = 5; 214 | } 215 | 216 | smpp_server->ip_blocklist_exempt_ips = cfg_get(grp, octstr_imm("ip-blocklist-exempt-ips")); 217 | 218 | cfg_get_integer(&smpp_server->default_max_open_acks, grp, octstr_imm("default-max-open-acks")); 219 | 220 | info(0, "SMPP ESME Default Max Open Acks set to %ld", smpp_server->default_max_open_acks); 221 | 222 | cfg_get_integer(&smpp_server->wait_ack_action, grp, octstr_imm("wait-ack-action")); 223 | 224 | info(0, "SMPP Wait ack behaviour %ld", smpp_server->wait_ack_action); 225 | 226 | debug("smpp", 0, "Blocking users for %ld seconds on %ld authentication failures", smpp_server->ip_blocklist_time, smpp_server->ip_blocklist_attempts); 227 | 228 | smpp_server->database_type = cfg_get(grp, octstr_imm("database-type")); 229 | smpp_server->database_config = cfg_get(grp, octstr_imm("database-config")); 230 | smpp_server->database_store_table = cfg_get(grp, octstr_imm("database-store-table")); 231 | smpp_server->database_user_table = cfg_get(grp, octstr_imm("database-user-table")); 232 | smpp_server->database_pdu_table = cfg_get(grp, octstr_imm("database-pdu-table")); 233 | smpp_server->database_route_table = cfg_get(grp, octstr_imm("database-route-table")); 234 | smpp_server->database_version_table = cfg_get(grp, octstr_imm("database-version-table")); 235 | 236 | if(!octstr_len(smpp_server->database_type)) { 237 | panic(0, "The SMPP server cannot function without a 'database-type' parameter"); 238 | } 239 | 240 | cfg_get_bool(&smpp_server->database_enable_queue, grp, octstr_imm("database-enable-queue")); 241 | 242 | smpp_server->database = smpp_database_init(smpp_server); 243 | 244 | if(smpp_server->database == NULL) { 245 | panic(0, "Error configuring database %s configuration %s", octstr_get_cstr(smpp_server->database_type), octstr_get_cstr(smpp_server->database_config)); 246 | } 247 | 248 | if(cfg_get_integer(&smpp_server->authentication_method, grp, octstr_imm("auth-method")) == -1) { 249 | smpp_server->authentication_method = SMPP_SERVER_AUTH_METHOD_DATABASE; 250 | tmp_str = cfg_get(grp, octstr_imm("auth-method")); 251 | if(!octstr_len(tmp_str)) { 252 | debug("smpp", 0, "No 'auth-method' specified, using database as default"); 253 | smpp_server->authentication_method = SMPP_SERVER_AUTH_METHOD_DATABASE; 254 | } else { 255 | /* Read a non-integer string */ 256 | if(octstr_case_compare(tmp_str, octstr_imm("database")) == 0) { 257 | debug("smpp", 0, "Authentication using database"); 258 | smpp_server->authentication_method = SMPP_SERVER_AUTH_METHOD_DATABASE; 259 | } else if(octstr_case_compare(tmp_str, octstr_imm("http")) == 0) { 260 | debug("smpp", 0, "Authentication using http"); 261 | smpp_server->authentication_method = SMPP_SERVER_AUTH_METHOD_HTTP; 262 | } else if(octstr_case_compare(tmp_str, octstr_imm("plugin")) == 0) { 263 | plugin_id = cfg_get(grp, octstr_imm("auth-plugin-id")); 264 | 265 | if(!octstr_len(plugin_id)) { 266 | panic(0, "Requested plugin based authentication but no 'auth-plugin-id' set"); 267 | } 268 | 269 | debug("smpp", 0, "Authentication using plugin"); 270 | smpp_server->authentication_method = SMPP_SERVER_AUTH_METHOD_PLUGIN; 271 | smpp_server->plugin_auth = smpp_plugin_init(smpp_server, plugin_id); 272 | if(smpp_server->plugin_auth == NULL) { 273 | panic(0, "Plugin '%s' initialization failed, cannot continue", octstr_get_cstr(plugin_id)); 274 | } else { 275 | if(!smpp_server->plugin_auth->authenticate) { 276 | panic(0, "Plugin '%s' has no registered auth function, cannot continue", octstr_get_cstr(plugin_id)); 277 | } 278 | } 279 | 280 | octstr_destroy(plugin_id); 281 | } else { 282 | panic(0, "Unknown auth method '%s'", octstr_get_cstr(tmp_str)); 283 | } 284 | } 285 | octstr_destroy(tmp_str); 286 | } 287 | 288 | smpp_server->auth_url = cfg_get(grp, octstr_imm("auth-url")); 289 | 290 | smpp_http_server_init(smpp_server); 291 | 292 | smpp_route_init(smpp_server); 293 | 294 | smpp_server->configured = 1; 295 | } 296 | } else { 297 | if (!smpp_server->configured) { 298 | panic(0, "No group 'ksmppd' configured in %s, cannot start", octstr_get_cstr(smpp_server->config_filename)); 299 | } else { 300 | error(0, "Unable to refresh configuration file %s, no 'ksmppd' group configured", octstr_get_cstr(smpp_server->config_filename)); 301 | } 302 | } 303 | 304 | } 305 | 306 | 307 | gw_rwlock_unlock(smpp_server->config_lock); 308 | 309 | return status; 310 | } 311 | 312 | 313 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_server.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_SERVER_H 64 | #include 65 | 66 | #define SMPP_SERVER_H 67 | #define SMPP_SERVER_NAME "KSMPPD" 68 | #define SMPP_SERVER_VERSION "0.6" 69 | 70 | #define SMPP_SERVER_AUTH_METHOD_DATABASE 1 71 | #define SMPP_SERVER_AUTH_METHOD_HTTP 2 72 | #define SMPP_SERVER_AUTH_METHOD_PLUGIN 4 73 | 74 | #define SMPP_SERVER_STATUS_STARTUP 1 75 | #define SMPP_SERVER_STATUS_RUNNING 2 76 | #define SMPP_SERVER_STATUS_LOG_REOPEN 4 77 | #define SMPP_SERVER_STATUS_SHUTDOWN 8 78 | 79 | #define SMPP_WAITACK_DISCONNECT 0 80 | #define SMPP_WAITACK_DROP 1 81 | 82 | #ifdef __cplusplus 83 | extern "C" { 84 | #endif 85 | 86 | typedef struct { 87 | Cfg *running_configuration; 88 | Octstr *config_filename; 89 | RWLock *config_lock; 90 | Octstr *server_id; 91 | 92 | List *bearerbox_outbound_queue; 93 | List *bearerbox_inbound_queue; 94 | 95 | int configured; 96 | 97 | volatile sig_atomic_t server_status; 98 | 99 | long smpp_port; 100 | 101 | int enable_ssl; 102 | 103 | void *esme_data; 104 | 105 | gw_prioqueue_t *inbound_queue; 106 | gw_prioqueue_t *outbound_queue; 107 | gw_prioqueue_t *simulation_queue; 108 | 109 | long num_inbound_queue_threads; 110 | long num_outbound_queue_threads; 111 | 112 | Counter *running_threads; 113 | 114 | Octstr *database_type; 115 | Octstr *database_config; 116 | Octstr *database_user_table; 117 | Octstr *database_store_table; 118 | Octstr *database_pdu_table; 119 | Octstr *database_route_table; 120 | Octstr *database_version_table; 121 | 122 | int database_enable_queue; 123 | 124 | 125 | void *database; 126 | void *bearerbox; 127 | void *routing; 128 | void *http_server; 129 | void *http_client; 130 | 131 | 132 | 133 | struct event_base *event_base; 134 | struct evconnlistener *event_listener; 135 | 136 | Counter *esme_counter; 137 | long authentication_method; 138 | Octstr *auth_url; 139 | 140 | struct SMPPPlugin *plugin_auth; 141 | struct SMPPPlugin *plugin_route; 142 | 143 | 144 | Dict *plugins; 145 | 146 | Dict *ip_blocklist; 147 | RWLock *ip_blocklist_lock; 148 | long ip_blocklist_time; 149 | long ip_blocklist_attempts; 150 | Octstr *ip_blocklist_exempt_ips; 151 | 152 | long default_max_open_acks; 153 | 154 | long wait_ack_action; 155 | } SMPPServer; 156 | 157 | SMPPServer *smpp_server_create(); 158 | void smpp_server_destroy(SMPPServer *smpp_server); 159 | int smpp_server_reconfigure(SMPPServer *smpp_server); 160 | 161 | #ifdef __cplusplus 162 | } 163 | #endif 164 | 165 | #endif /* SMPP_SERVER_H */ 166 | 167 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_server_cfg.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | #include "gwlib/gwlib.h" 63 | 64 | 65 | int smpp_server_cfg_is_allowed_in_group(Octstr *group, Octstr *variable) { 66 | Octstr *groupstr; 67 | 68 | groupstr = octstr_imm("group"); 69 | 70 | #define OCTSTR(name) \ 71 | if (octstr_compare(octstr_imm(#name), variable) == 0) \ 72 | return 1; 73 | #define SINGLE_GROUP(name, fields) \ 74 | if (octstr_compare(octstr_imm(#name), group) == 0) { \ 75 | if (octstr_compare(groupstr, variable) == 0) \ 76 | return 1; \ 77 | fields \ 78 | return 0; \ 79 | } 80 | #define MULTI_GROUP(name, fields) \ 81 | if (octstr_compare(octstr_imm(#name), group) == 0) { \ 82 | if (octstr_compare(groupstr, variable) == 0) \ 83 | return 1; \ 84 | fields \ 85 | return 0; \ 86 | } 87 | #include "smpp_server_cfg.def" 88 | 89 | return 0; 90 | } 91 | 92 | int smpp_server_cfg_is_single_group(Octstr *query) { 93 | #define OCTSTR(name) 94 | #define SINGLE_GROUP(name, fields) \ 95 | if (octstr_compare(octstr_imm(#name), query) == 0) \ 96 | return 1; 97 | #define MULTI_GROUP(name, fields) \ 98 | if (octstr_compare(octstr_imm(#name), query) == 0) \ 99 | return 0; 100 | #include "smpp_server_cfg.def" 101 | return 0; 102 | } 103 | 104 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_server_cfg.def: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | 64 | #ifndef OCTSTR 65 | #error OCTSTR not defined. 66 | #endif 67 | 68 | #ifndef SINGLE_GROUP 69 | #error SINGLE_GROUP not defined. 70 | #endif 71 | 72 | #ifndef MULTI_GROUP 73 | #error MULTI_GROUP not defined. 74 | #endif 75 | 76 | SINGLE_GROUP(ksmppd, 77 | OCTSTR(id) 78 | OCTSTR(log-file) 79 | OCTSTR(log-level) 80 | 81 | OCTSTR(smpp-port) 82 | 83 | OCTSTR(database-type) 84 | OCTSTR(database-config) 85 | OCTSTR(database-user-table) 86 | OCTSTR(database-store-table) 87 | OCTSTR(database-enable-queue) 88 | OCTSTR(database-pdu-table) 89 | OCTSTR(database-route-table) 90 | OCTSTR(database-version-table) 91 | 92 | OCTSTR(default-max-open-acks) 93 | 94 | OCTSTR(inbound-queue-threads) 95 | OCTSTR(outbound-queue-threads) 96 | 97 | OCTSTR(auth-method) 98 | OCTSTR(auth-url) 99 | OCTSTR(auth-plugin-id) 100 | 101 | OCTSTR(ip-blocklist-time) 102 | OCTSTR(ip-blocklist-attempts) 103 | OCTSTR(ip-blocklist-exempt-ips) 104 | 105 | OCTSTR(wait-ack-action) 106 | ) 107 | 108 | SINGLE_GROUP(smpp-routing, 109 | OCTSTR(routing-method) 110 | OCTSTR(http-routing-url) 111 | OCTSTR(http-num-callers) 112 | OCTSTR(http-max-outstanding-requests) 113 | OCTSTR(plugin-id) 114 | ) 115 | 116 | SINGLE_GROUP(http-server, 117 | OCTSTR(port) 118 | OCTSTR(password) 119 | OCTSTR(interface) 120 | OCTSTR(ssl) 121 | ) 122 | 123 | MULTI_GROUP(bearerbox-connection, 124 | OCTSTR(id) 125 | OCTSTR(host) 126 | OCTSTR(port) 127 | OCTSTR(ssl) 128 | ) 129 | 130 | MULTI_GROUP(ksmppd-plugin, 131 | OCTSTR(id) 132 | OCTSTR(path) 133 | OCTSTR(init-function) 134 | OCTSTR(args) 135 | ) 136 | 137 | 138 | #undef OCTSTR 139 | #undef SINGLE_GROUP 140 | #undef MULTI_GROUP 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_server_cfg.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #ifndef SMPP_SERVER_CFG_H 64 | #define SMPP_SERVER_CFG_H 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | int smpp_server_cfg_is_allowed_in_group(Octstr *group, Octstr *variable); 71 | int smpp_server_cfg_is_single_group(Octstr *query); 72 | 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | 78 | #endif /* SMPP_SERVER_CFG_H */ 79 | 80 | -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_uuid.c: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | #include "gwlib/gwlib.h" 64 | 65 | 66 | Octstr *smpp_uuid_create() { 67 | char buffer[UUID_STR_LEN + 1]; 68 | uuid_t my_uuid; 69 | 70 | uuid_generate(my_uuid); 71 | uuid_unparse(my_uuid, buffer); 72 | 73 | return octstr_create(buffer); 74 | 75 | } 76 | 77 | 78 | Octstr *smpp_uuid_get(uuid_t my_uuid) { 79 | char buffer[UUID_STR_LEN + 1]; 80 | 81 | uuid_unparse(my_uuid, buffer); 82 | 83 | return octstr_create(buffer); 84 | 85 | } -------------------------------------------------------------------------------- /smpp/libsmpp/smpp_uuid.h: -------------------------------------------------------------------------------- 1 | /* ==================================================================== 2 | * KSMPPD Software License, Version 1.0 3 | * 4 | * Copyright (c) 2016 Kurt Neo 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The end-user documentation included with the redistribution, 20 | * if any, must include the following acknowledgment: 21 | * "This product includes software developed by 22 | * Kurt Neo & the Kannel Group (http://www.kannel.org/)." 23 | * Alternately, this acknowledgment may appear in the software itself, 24 | * if and wherever such third-party acknowledgments normally appear. 25 | * 26 | * 4. The names "KSMPPD" and "KSMPPD" must not be used to 27 | * endorse or promote products derived from this software without 28 | * prior written permission. For written permission, please 29 | * contact kneodev@gmail.com 30 | * 31 | * 5. Products derived from this software may not be called "KSMPPD", 32 | * nor may "KSMPPD" appear in their name, without prior written 33 | * permission of the Kurt Neo. 34 | * 35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 | * DISCLAIMED. IN NO EVENT SHALL KURT NEO OR CONTRIBUTORS 39 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 40 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 41 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 43 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 44 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 45 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 | * ==================================================================== 47 | * 48 | * This software consists of voluntary contributions made by Kurt Neo. 49 | * 50 | * KSMPPD or "Kurt's SMPP Daemon" were written by Kurt Neo. 51 | * 52 | * If you would like to donate to this project you may do so via Bitcoin to 53 | * the address: 1NhLkTDiZtFTJMefvjQY4pUWM3jD641jWN 54 | * 55 | * If you require commercial support for this software you can contact 56 | * 57 | * Kurt Neo 58 | * 59 | * This product includes software developed by the Kannel Group (http://www.kannel.org/). 60 | * 61 | */ 62 | 63 | 64 | #ifndef SMPP_UUID_H 65 | #define SMPP_UUID_H 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | Octstr *smpp_uuid_create(); 72 | Octstr *smpp_uuid_get(uuid_t my_uuid); 73 | 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #endif /* SMPP_UUID_H */ 80 | 81 | --------------------------------------------------------------------------------