Kannel: Open Source WAP and SMS gateway  svn-r5335
shared.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2018 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * shared.c - some utility routines shared by all Kannel boxes
59  *
60  * Lars Wirzenius
61  */
62 
63 #include <errno.h>
64 #include <sys/unistd.h>
65 #include <libxml/xmlversion.h>
66 
67 #include "gwlib/gwlib.h"
68 #include "shared.h"
69 
70 
72 
73 
74 /***********************************************************************
75  * Communication with the bearerbox.
76  */
77 
78 /* this is a static connection if only *one* boxc connection is
79  * established from a foobarbox to bearerbox. */
81 
82 
84 {
85  Connection *conn;
86 
87 #ifdef HAVE_LIBSSL
88  if (ssl)
89  conn = conn_open_ssl(host, port, NULL, our_host);
90  /* XXX add certkeyfile to be given to conn_open_ssl */
91  else
92 #endif /* HAVE_LIBSSL */
93  conn = conn_open_tcp(host, port, our_host);
94  if (conn == NULL)
95  return NULL;
96 
97  if (ssl)
98  info(0, "Connected to bearerbox at %s port %d using SSL.",
100  else
101  info(0, "Connected to bearerbox at %s port %d.",
103 
104  return conn;
105 }
106 
107 
109 {
111  if (bb_conn == NULL)
112  panic(0, "Couldn't connect to the bearerbox.");
113 }
114 
115 
117 {
118  conn_destroy(conn);
119 }
120 
121 
123 {
125  bb_conn = NULL;
126 }
127 
128 
130 {
131  Octstr *pack;
132 
133  pack = msg_pack(pmsg);
134  if (conn_write_withlen(conn, pack) == -1)
135  error(0, "Couldn't write Msg to bearerbox.");
136 
137  msg_destroy(pmsg);
138  octstr_destroy(pack);
139 }
140 
141 
143 {
145 }
146 
147 
149 {
150 
151  Octstr *pack;
152 
153  pack = msg_pack(msg);
154  if (conn_write_withlen(conn, pack) == -1) {
155  error(0, "Couldn't deliver Msg to bearerbox.");
156  octstr_destroy(pack);
157  return -1;
158  }
159 
160  octstr_destroy(pack);
161  msg_destroy(msg);
162  return 0;
163 }
164 
165 
167 {
169 }
170 
171 
172 int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
173 {
174  int ret;
175  Octstr *pack;
176 
177  pack = NULL;
178  *msg = NULL;
179  while (program_status != shutting_down) {
180  pack = conn_read_withlen(conn);
181  gw_claim_area(pack);
182  if (pack != NULL)
183  break;
184 
185  if (conn_error(conn)) {
186  error(0, "Error reading from bearerbox, disconnecting.");
187  return -1;
188  }
189  if (conn_eof(conn)) {
190  error(0, "Connection closed by the bearerbox.");
191  return -1;
192  }
193 
194  ret = conn_wait(conn, seconds);
195  if (ret < 0) {
196  error(0, "Connection to bearerbox broke.");
197  return -1;
198  }
199  else if (ret == 1) {
200  /* debug("gwlib.gwlib", 0, "Connection to bearerbox timed out after %.2f seconds.", seconds); */
201  return 1;
202  }
203  }
204 
205  if (pack == NULL)
206  return -1;
207 
208  *msg = msg_unpack(pack);
209  octstr_destroy(pack);
210 
211  if (*msg == NULL) {
212  error(0, "Failed to unpack data!");
213  return -1;
214  }
215 
216  return 0;
217 }
218 
219 
220 int read_from_bearerbox(Msg **msg, double seconds)
221 {
222  return read_from_bearerbox_real(bb_conn, msg, seconds);
223 }
224 
225 
226 /*****************************************************************************
227  *
228  * Function validates an OSI date. Return unmodified octet string date when it
229  * is valid, NULL otherwise.
230  */
231 
233 {
234  long date_value;
235 
236  if (octstr_get_char(date, 4) != '-')
237  goto error;
238  if (octstr_get_char(date, 7) != '-')
239  goto error;
240  if (octstr_get_char(date, 10) != 'T')
241  goto error;
242  if (octstr_get_char(date, 13) != ':')
243  goto error;
244  if (octstr_get_char(date, 16) != ':')
245  goto error;
246  if (octstr_get_char(date, 19) != 'Z')
247  goto error;
248 
249  if (octstr_parse_long(&date_value, date, 0, 10) < 0)
250  goto error;
251  if (octstr_parse_long(&date_value, date, 5, 10) < 0)
252  goto error;
253  if (date_value < 1 || date_value > 12)
254  goto error;
255  if (octstr_parse_long(&date_value, date, 8, 10) < 0)
256  goto error;
257  if (date_value < 1 || date_value > 31)
258  goto error;
259  if (octstr_parse_long(&date_value, date, 11, 10) < 0)
260  goto error;
261  if (date_value < 0 || date_value > 23)
262  goto error;
263  if (octstr_parse_long(&date_value, date, 14, 10) < 0)
264  goto error;
265  if (date_value < 0 || date_value > 59)
266  goto error;
267  if (date_value < 0 || date_value > 59)
268  goto error;
269  if (octstr_parse_long(&date_value, date, 17, 10) < 0)
270  goto error;
271 
272  return date;
273 
274 error:
275  warning(0, "parse_date: not an ISO date");
276  return NULL;
277 }
278 
279 int restart_box(char **argv)
280 {
281  int rc;
282 
283  if (!(rc = fork())) {
284  /*
285  * Sleep a while in order to get father
286  * process time to cleanup things
287  */
288  gwthread_sleep(1.0);
289  if (execvp(argv[0],argv) == -1)
290  error(errno, "Unable to start new process.");
291  } else if (rc == -1)
292  error(errno, "Could not restart, exiting...");
293 
294  return rc == -1 ? -1 : 0;
295 }
296 
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
Definition: http.c:2014
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
Definition: conn.c:496
Connection * connect_to_bearerbox_real(Octstr *host, int port, int ssl, Octstr *our_host)
Definition: shared.c:83
#define msg_unpack(os)
Definition: msg.h:183
int ssl
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
Definition: shared.c:172
Octstr * parse_date(Octstr *date)
Definition: shared.c:232
int restart_box(char **argv)
Definition: shared.c:279
program_status
Definition: shared.h:79
int read_from_bearerbox(Msg **msg, double seconds)
Definition: shared.c:220
static Octstr * host
Definition: fakesmsc.c:122
int conn_eof(Connection *conn)
Definition: conn.c:705
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int deliver_to_bearerbox_real(Connection *conn, Msg *msg)
Definition: shared.c:148
static Octstr * our_host
Definition: radius_acct.c:86
Definition: msg.h:79
void conn_destroy(Connection *conn)
Definition: conn.c:627
void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
Definition: shared.c:108
void msg_destroy(Msg *msg)
Definition: msg.c:132
void close_connection_to_bearerbox_real(Connection *conn)
Definition: shared.c:116
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void gwthread_sleep(double seconds)
Octstr * conn_read_withlen(Connection *conn)
Definition: conn.c:1169
int deliver_to_bearerbox(Msg *msg)
Definition: shared.c:166
int conn_write_withlen(Connection *conn, Octstr *data)
Definition: conn.c:1075
void close_connection_to_bearerbox(void)
Definition: shared.c:122
void write_to_bearerbox(Msg *pmsg)
Definition: shared.c:142
Definition: octstr.c:118
void write_to_bearerbox_real(Connection *conn, Msg *pmsg)
Definition: shared.c:129
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
#define panic
Definition: log.h:87
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:749
Octstr * msg_pack(Msg *msg)
Definition: msg.c:181
static int date(int hex)
int conn_error(Connection *conn)
Definition: conn.c:716
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static Connection * bb_conn
Definition: shared.c:80
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.