oversip 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS.txt +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +16 -0
- data/Rakefile +55 -0
- data/bin/oversip +182 -0
- data/ext/common/c_util.h +74 -0
- data/ext/common/ruby_c_util.h +88 -0
- data/ext/sip_parser/common_headers.h +209 -0
- data/ext/sip_parser/ext_help.h +18 -0
- data/ext/sip_parser/extconf.rb +3 -0
- data/ext/sip_parser/sip_parser.c +29649 -0
- data/ext/sip_parser/sip_parser.h +227 -0
- data/ext/sip_parser/sip_parser_ruby.c +1292 -0
- data/ext/stud/extconf.rb +27 -0
- data/ext/stud/stud.tar.gz +0 -0
- data/ext/stun/ext_help.h +16 -0
- data/ext/stun/extconf.rb +3 -0
- data/ext/stun/stun_ruby.c +391 -0
- data/ext/utils/ext_help.h +14 -0
- data/ext/utils/extconf.rb +3 -0
- data/ext/utils/haproxy_protocol.c +6163 -0
- data/ext/utils/haproxy_protocol.h +27 -0
- data/ext/utils/ip_utils.c +5952 -0
- data/ext/utils/ip_utils.h +61 -0
- data/ext/utils/outbound_utils.c +3227 -0
- data/ext/utils/outbound_utils.h +27 -0
- data/ext/utils/utils_ruby.c +384 -0
- data/ext/utils/utils_ruby.h +75 -0
- data/ext/websocket_framing_utils/ext_help.h +18 -0
- data/ext/websocket_framing_utils/extconf.rb +3 -0
- data/ext/websocket_framing_utils/ws_framing_utils.h +46 -0
- data/ext/websocket_framing_utils/ws_framing_utils_ruby.c +135 -0
- data/ext/websocket_http_parser/ext_help.h +18 -0
- data/ext/websocket_http_parser/extconf.rb +3 -0
- data/ext/websocket_http_parser/ws_http_parser.c +2598 -0
- data/ext/websocket_http_parser/ws_http_parser.h +86 -0
- data/ext/websocket_http_parser/ws_http_parser_ruby.c +630 -0
- data/lib/oversip/config.rb +541 -0
- data/lib/oversip/config_validators.rb +126 -0
- data/lib/oversip/errors.rb +7 -0
- data/lib/oversip/fiber_pool.rb +56 -0
- data/lib/oversip/launcher.rb +507 -0
- data/lib/oversip/logger.rb +170 -0
- data/lib/oversip/master_process.rb +67 -0
- data/lib/oversip/posix_mq.rb +121 -0
- data/lib/oversip/proxies_config.rb +169 -0
- data/lib/oversip/ruby_ext/eventmachine.rb +38 -0
- data/lib/oversip/sip/client_transaction.rb +587 -0
- data/lib/oversip/sip/constants.rb +87 -0
- data/lib/oversip/sip/grammar/name_addr.rb +27 -0
- data/lib/oversip/sip/grammar/uri.rb +116 -0
- data/lib/oversip/sip/launcher.rb +180 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tcp_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_tls_tunnel_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv4_udp_server.rb +20 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tcp_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_client.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_tls_tunnel_server.rb +21 -0
- data/lib/oversip/sip/listeners/ipv6_udp_server.rb +20 -0
- data/lib/oversip/sip/listeners/reactor.rb +39 -0
- data/lib/oversip/sip/listeners/tcp_client.rb +73 -0
- data/lib/oversip/sip/listeners/tcp_reactor.rb +185 -0
- data/lib/oversip/sip/listeners/tcp_server.rb +71 -0
- data/lib/oversip/sip/listeners/tls_client.rb +117 -0
- data/lib/oversip/sip/listeners/tls_server.rb +70 -0
- data/lib/oversip/sip/listeners/tls_tunnel_reactor.rb +113 -0
- data/lib/oversip/sip/listeners/tls_tunnel_server.rb +61 -0
- data/lib/oversip/sip/listeners/udp_reactor.rb +213 -0
- data/lib/oversip/sip/listeners.rb +28 -0
- data/lib/oversip/sip/logic.rb +14 -0
- data/lib/oversip/sip/message.rb +168 -0
- data/lib/oversip/sip/message_processor.rb +202 -0
- data/lib/oversip/sip/modules/core.rb +200 -0
- data/lib/oversip/sip/modules/registrar_without_path.rb +75 -0
- data/lib/oversip/sip/modules/user_assertion.rb +123 -0
- data/lib/oversip/sip/proxy.rb +460 -0
- data/lib/oversip/sip/request.rb +128 -0
- data/lib/oversip/sip/response.rb +30 -0
- data/lib/oversip/sip/rfc3263.rb +646 -0
- data/lib/oversip/sip/server_transaction.rb +295 -0
- data/lib/oversip/sip/sip.rb +74 -0
- data/lib/oversip/sip/tags.rb +39 -0
- data/lib/oversip/sip/timers.rb +55 -0
- data/lib/oversip/sip/transport_manager.rb +129 -0
- data/lib/oversip/syslogger_process.rb +119 -0
- data/lib/oversip/tls.rb +179 -0
- data/lib/oversip/utils.rb +25 -0
- data/lib/oversip/version.rb +23 -0
- data/lib/oversip/websocket/constants.rb +56 -0
- data/lib/oversip/websocket/default_policy.rb +19 -0
- data/lib/oversip/websocket/http_request.rb +63 -0
- data/lib/oversip/websocket/launcher.rb +207 -0
- data/lib/oversip/websocket/listeners/ipv4_tcp_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv4_tls_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv4_tls_tunnel_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv6_tcp_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv6_tls_server.rb +15 -0
- data/lib/oversip/websocket/listeners/ipv6_tls_tunnel_server.rb +15 -0
- data/lib/oversip/websocket/listeners/tcp_server.rb +265 -0
- data/lib/oversip/websocket/listeners/tls_server.rb +69 -0
- data/lib/oversip/websocket/listeners/tls_tunnel_server.rb +100 -0
- data/lib/oversip/websocket/listeners.rb +12 -0
- data/lib/oversip/websocket/ws_app.rb +75 -0
- data/lib/oversip/websocket/ws_apps/ipv4_ws_sip_app.rb +21 -0
- data/lib/oversip/websocket/ws_apps/ipv4_wss_sip_app.rb +21 -0
- data/lib/oversip/websocket/ws_apps/ipv6_ws_sip_app.rb +21 -0
- data/lib/oversip/websocket/ws_apps/ipv6_wss_sip_app.rb +22 -0
- data/lib/oversip/websocket/ws_apps/ws_autobahn_app.rb +23 -0
- data/lib/oversip/websocket/ws_apps/ws_sip_app.rb +156 -0
- data/lib/oversip/websocket/ws_apps.rb +9 -0
- data/lib/oversip/websocket/ws_framing.rb +597 -0
- data/lib/oversip.rb +59 -0
- data/test/oversip_test_helper.rb +20 -0
- data/test/test_http_parser.rb +73 -0
- data/test/test_sip_parser.rb +139 -0
- metadata +256 -0
|
@@ -0,0 +1,1292 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include "ext_help.h"
|
|
3
|
+
#include "sip_parser.h"
|
|
4
|
+
#include "common_headers.h"
|
|
5
|
+
#include "../utils/utils_ruby.h"
|
|
6
|
+
#include "../common/c_util.h"
|
|
7
|
+
#include "../common/ruby_c_util.h"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
static VALUE my_rb_str_tel_number_clean(const char*, size_t);
|
|
11
|
+
|
|
12
|
+
static VALUE mOverSIP;
|
|
13
|
+
static VALUE eOverSIPError;
|
|
14
|
+
|
|
15
|
+
static VALUE mSIP;
|
|
16
|
+
static VALUE cSIPMessageParser;
|
|
17
|
+
static VALUE eSIPMessageParserError;
|
|
18
|
+
static VALUE cSIPMessage;
|
|
19
|
+
static VALUE cSIPRequest;
|
|
20
|
+
static VALUE cSIPResponse;
|
|
21
|
+
static VALUE cUri;
|
|
22
|
+
static VALUE cNameAddr;
|
|
23
|
+
|
|
24
|
+
static ID id_headers;
|
|
25
|
+
static ID id_parsed;
|
|
26
|
+
static ID id_sip_method;
|
|
27
|
+
static ID id_is_unknown_method;
|
|
28
|
+
static ID id_ruri;
|
|
29
|
+
static ID id_status_code;
|
|
30
|
+
static ID id_reason_phrase;
|
|
31
|
+
static ID id_sip_version;
|
|
32
|
+
static ID id_via_sent_by_host;
|
|
33
|
+
static ID id_via_sent_by_port;
|
|
34
|
+
static ID id_via_branch;
|
|
35
|
+
static ID id_via_branch_rfc3261;
|
|
36
|
+
static ID id_via_received;
|
|
37
|
+
static ID id_via_has_rport;
|
|
38
|
+
static ID id_via_has_alias;
|
|
39
|
+
static ID id_via_core_value;
|
|
40
|
+
static ID id_via_params;
|
|
41
|
+
static ID id_num_vias;
|
|
42
|
+
static ID id_call_id;
|
|
43
|
+
static ID id_cseq;
|
|
44
|
+
static ID id_max_forwards;
|
|
45
|
+
static ID id_content_length;
|
|
46
|
+
static ID id_from;
|
|
47
|
+
static ID id_from_tag;
|
|
48
|
+
static ID id_to;
|
|
49
|
+
static ID id_to_tag;
|
|
50
|
+
static ID id_routes;
|
|
51
|
+
static ID id_contact;
|
|
52
|
+
static ID id_contact_params;
|
|
53
|
+
static ID id_require;
|
|
54
|
+
static ID id_proxy_require;
|
|
55
|
+
static ID id_supported;
|
|
56
|
+
static ID id_hdr_via;
|
|
57
|
+
static ID id_hdr_from;
|
|
58
|
+
static ID id_hdr_to;
|
|
59
|
+
static ID id_hdr_route;
|
|
60
|
+
|
|
61
|
+
static ID id_display_name;
|
|
62
|
+
static ID id_uri;
|
|
63
|
+
static ID id_uri_scheme;
|
|
64
|
+
static ID id_uri_user;
|
|
65
|
+
static ID id_uri_host;
|
|
66
|
+
static ID id_uri_host_type;
|
|
67
|
+
static ID id_uri_port;
|
|
68
|
+
static ID id_uri_params;
|
|
69
|
+
static ID id_uri_transport_param;
|
|
70
|
+
static ID id_uri_lr_param;
|
|
71
|
+
static ID id_uri_ob_param;
|
|
72
|
+
static ID id_uri_ovid_param;
|
|
73
|
+
static ID id_uri_phone_context_param;
|
|
74
|
+
static ID id_uri_headers;
|
|
75
|
+
|
|
76
|
+
static VALUE symbol_outbound_keepalive;
|
|
77
|
+
static VALUE symbol_INVITE;
|
|
78
|
+
static VALUE symbol_OPTIONS;
|
|
79
|
+
static VALUE symbol_INVITE;
|
|
80
|
+
static VALUE symbol_ACK;
|
|
81
|
+
static VALUE symbol_CANCEL;
|
|
82
|
+
static VALUE symbol_PRACK;
|
|
83
|
+
static VALUE symbol_BYE;
|
|
84
|
+
static VALUE symbol_REFER;
|
|
85
|
+
static VALUE symbol_INFO;
|
|
86
|
+
static VALUE symbol_UPDATE;
|
|
87
|
+
static VALUE symbol_OPTIONS;
|
|
88
|
+
static VALUE symbol_REGISTER;
|
|
89
|
+
static VALUE symbol_MESSAGE;
|
|
90
|
+
static VALUE symbol_SUBSCRIBE;
|
|
91
|
+
static VALUE symbol_NOTIFY;
|
|
92
|
+
static VALUE symbol_PUBLISH;
|
|
93
|
+
static VALUE symbol_PULL;
|
|
94
|
+
static VALUE symbol_PUSH;
|
|
95
|
+
static VALUE symbol_STORE;
|
|
96
|
+
static VALUE symbol_sip;
|
|
97
|
+
static VALUE symbol_sips;
|
|
98
|
+
static VALUE symbol_tel;
|
|
99
|
+
static VALUE symbol_udp;
|
|
100
|
+
static VALUE symbol_tcp;
|
|
101
|
+
static VALUE symbol_tls;
|
|
102
|
+
static VALUE symbol_sctp;
|
|
103
|
+
static VALUE symbol_ws;
|
|
104
|
+
static VALUE symbol_wss;
|
|
105
|
+
static VALUE symbol_domain;
|
|
106
|
+
static VALUE symbol_ipv4;
|
|
107
|
+
static VALUE symbol_ipv6;
|
|
108
|
+
static VALUE symbol_ipv6_reference;
|
|
109
|
+
|
|
110
|
+
static VALUE string_Via;
|
|
111
|
+
static VALUE string_From;
|
|
112
|
+
static VALUE string_To;
|
|
113
|
+
static VALUE string_CSeq;
|
|
114
|
+
static VALUE string_Call_ID;
|
|
115
|
+
static VALUE string_Max_Forwards;
|
|
116
|
+
static VALUE string_Content_Length;
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
static void data_type(void *parser, enum data_type data_type)
|
|
122
|
+
{
|
|
123
|
+
TRACE();
|
|
124
|
+
VALUE parsed;
|
|
125
|
+
sip_message_parser *sp = (sip_message_parser*)parser;
|
|
126
|
+
|
|
127
|
+
switch(data_type) {
|
|
128
|
+
case sip_request:
|
|
129
|
+
parsed = rb_obj_alloc(cSIPRequest);
|
|
130
|
+
rb_ivar_set(parsed, id_headers, rb_hash_new());
|
|
131
|
+
sp->parsed = parsed;
|
|
132
|
+
break;
|
|
133
|
+
case sip_response:
|
|
134
|
+
parsed = rb_obj_alloc(cSIPResponse);
|
|
135
|
+
rb_ivar_set(parsed, id_headers, rb_hash_new());
|
|
136
|
+
sp->parsed = parsed;
|
|
137
|
+
break;
|
|
138
|
+
case outbound_keepalive:
|
|
139
|
+
parsed = symbol_outbound_keepalive;
|
|
140
|
+
sp->parsed = parsed;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
/* NOTE: The parsing can require multiple invocations of the parser#execute() so
|
|
144
|
+
* we need to store the in-process message (Request or Response) in an attribute
|
|
145
|
+
* within the parser (if not it would be garbage collected as it has been declared
|
|
146
|
+
* as a VALUE variable). */
|
|
147
|
+
rb_ivar_set(sp->ruby_sip_parser, id_parsed, parsed);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
static void init_component(VALUE parsed, enum component msg_component)
|
|
152
|
+
{
|
|
153
|
+
switch(msg_component) {
|
|
154
|
+
case component_ruri: rb_ivar_set(parsed, id_ruri, rb_obj_alloc(cUri)); break;
|
|
155
|
+
case component_from: rb_ivar_set(parsed, id_from, rb_obj_alloc(cNameAddr)); break;
|
|
156
|
+
case component_to: rb_ivar_set(parsed, id_to, rb_obj_alloc(cNameAddr)); break;
|
|
157
|
+
case component_route: rb_ivar_set(parsed, id_routes, rb_ary_new()); break;
|
|
158
|
+
case component_route_uri: rb_ary_push(rb_ivar_get(parsed, id_routes), rb_obj_alloc(cNameAddr)); break;
|
|
159
|
+
case component_contact: rb_ivar_set(parsed, id_contact, rb_obj_alloc(cNameAddr)); break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
static void header(VALUE parsed, const char *hdr_field, size_t hdr_field_len, const char *hdr_value, size_t hdr_value_len, enum header_field hdr_field_name)
|
|
165
|
+
{
|
|
166
|
+
TRACE();
|
|
167
|
+
char *ch, *end;
|
|
168
|
+
VALUE v, f, el;
|
|
169
|
+
VALUE headers, array;
|
|
170
|
+
|
|
171
|
+
/* Header name. */
|
|
172
|
+
f = headerize(hdr_field, hdr_field_len);
|
|
173
|
+
|
|
174
|
+
/* Header value. */
|
|
175
|
+
v = RB_STR_UTF8_NEW(hdr_value, hdr_value_len);
|
|
176
|
+
|
|
177
|
+
headers = rb_ivar_get(parsed, id_headers);
|
|
178
|
+
|
|
179
|
+
/* Here we have the header name capitalized in variable f. */
|
|
180
|
+
el = rb_hash_lookup(headers, f);
|
|
181
|
+
switch(TYPE(el)) {
|
|
182
|
+
case T_ARRAY:
|
|
183
|
+
rb_ary_push(el, v);
|
|
184
|
+
break;
|
|
185
|
+
default:
|
|
186
|
+
array = rb_hash_aset(headers, f, rb_ary_new3(1, v));
|
|
187
|
+
switch(hdr_field_name) {
|
|
188
|
+
case header_field_any:
|
|
189
|
+
break;
|
|
190
|
+
case header_field_via:
|
|
191
|
+
rb_ivar_set(parsed, id_hdr_via, array);
|
|
192
|
+
break;
|
|
193
|
+
case header_field_from:
|
|
194
|
+
rb_ivar_set(parsed, id_hdr_from, v);
|
|
195
|
+
break;
|
|
196
|
+
case header_field_to:
|
|
197
|
+
rb_ivar_set(parsed, id_hdr_to, v);
|
|
198
|
+
break;
|
|
199
|
+
case header_field_route:
|
|
200
|
+
rb_ivar_set(parsed, id_hdr_route, array);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
static void msg_method(VALUE parsed, const char *at, size_t length, enum method method)
|
|
208
|
+
{
|
|
209
|
+
TRACE();
|
|
210
|
+
VALUE v;
|
|
211
|
+
|
|
212
|
+
switch(method) {
|
|
213
|
+
/* If the method is known store it as a symbol (i.e. :INVITE). */
|
|
214
|
+
case method_INVITE:
|
|
215
|
+
rb_ivar_set(parsed, id_sip_method, symbol_INVITE);
|
|
216
|
+
break;
|
|
217
|
+
case method_ACK:
|
|
218
|
+
rb_ivar_set(parsed, id_sip_method, symbol_ACK);
|
|
219
|
+
break;
|
|
220
|
+
case method_CANCEL:
|
|
221
|
+
rb_ivar_set(parsed, id_sip_method, symbol_CANCEL);
|
|
222
|
+
break;
|
|
223
|
+
case method_PRACK:
|
|
224
|
+
rb_ivar_set(parsed, id_sip_method, symbol_PRACK);
|
|
225
|
+
break;
|
|
226
|
+
case method_BYE:
|
|
227
|
+
rb_ivar_set(parsed, id_sip_method, symbol_BYE);
|
|
228
|
+
break;
|
|
229
|
+
case method_REFER:
|
|
230
|
+
rb_ivar_set(parsed, id_sip_method, symbol_REFER);
|
|
231
|
+
break;
|
|
232
|
+
case method_INFO:
|
|
233
|
+
rb_ivar_set(parsed, id_sip_method, symbol_INFO);
|
|
234
|
+
break;
|
|
235
|
+
case method_UPDATE:
|
|
236
|
+
rb_ivar_set(parsed, id_sip_method, symbol_UPDATE);
|
|
237
|
+
break;
|
|
238
|
+
case method_OPTIONS:
|
|
239
|
+
rb_ivar_set(parsed, id_sip_method, symbol_OPTIONS);
|
|
240
|
+
break;
|
|
241
|
+
case method_REGISTER:
|
|
242
|
+
rb_ivar_set(parsed, id_sip_method, symbol_REGISTER);
|
|
243
|
+
break;
|
|
244
|
+
case method_MESSAGE:
|
|
245
|
+
rb_ivar_set(parsed, id_sip_method, symbol_MESSAGE);
|
|
246
|
+
break;
|
|
247
|
+
case method_SUBSCRIBE:
|
|
248
|
+
rb_ivar_set(parsed, id_sip_method, symbol_SUBSCRIBE);
|
|
249
|
+
break;
|
|
250
|
+
case method_NOTIFY:
|
|
251
|
+
rb_ivar_set(parsed, id_sip_method, symbol_NOTIFY);
|
|
252
|
+
break;
|
|
253
|
+
case method_PUBLISH:
|
|
254
|
+
rb_ivar_set(parsed, id_sip_method, symbol_PUBLISH);
|
|
255
|
+
break;
|
|
256
|
+
case method_PULL:
|
|
257
|
+
rb_ivar_set(parsed, id_sip_method, symbol_PULL);
|
|
258
|
+
break;
|
|
259
|
+
case method_PUSH:
|
|
260
|
+
rb_ivar_set(parsed, id_sip_method, symbol_PUSH);
|
|
261
|
+
break;
|
|
262
|
+
case method_STORE:
|
|
263
|
+
rb_ivar_set(parsed, id_sip_method, symbol_STORE);
|
|
264
|
+
break;
|
|
265
|
+
/* If the method is unknown store it as a string (i.e. "CHICKEN") and set the
|
|
266
|
+
attribute @is_unknown_method to true. */
|
|
267
|
+
case method_unknown:
|
|
268
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
269
|
+
rb_ivar_set(parsed, id_sip_method, v);
|
|
270
|
+
rb_ivar_set(parsed, id_is_unknown_method, Qtrue);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
static void msg_status_code(VALUE parsed, const char *at, size_t length)
|
|
277
|
+
{
|
|
278
|
+
TRACE();
|
|
279
|
+
VALUE v;
|
|
280
|
+
|
|
281
|
+
v = INT2FIX(str_to_int(at, length));
|
|
282
|
+
rb_ivar_set(parsed, id_status_code, v);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
static void msg_reason_phrase(VALUE parsed, const char *at, size_t length)
|
|
287
|
+
{
|
|
288
|
+
TRACE();
|
|
289
|
+
VALUE v;
|
|
290
|
+
|
|
291
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
292
|
+
rb_ivar_set(parsed, id_reason_phrase, v);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
static void msg_sip_version(VALUE parsed, const char *at, size_t length)
|
|
297
|
+
{
|
|
298
|
+
TRACE();
|
|
299
|
+
VALUE v;
|
|
300
|
+
|
|
301
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
302
|
+
rb_ivar_set(parsed, id_sip_version, v);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
static void msg_via_sent_by_host(VALUE parsed, const char *at, size_t length)
|
|
307
|
+
{
|
|
308
|
+
TRACE();
|
|
309
|
+
VALUE v;
|
|
310
|
+
|
|
311
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
312
|
+
rb_ivar_set(parsed, id_via_sent_by_host, v);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
static void msg_via_sent_by_port(VALUE parsed, const char *at, size_t length)
|
|
317
|
+
{
|
|
318
|
+
TRACE();
|
|
319
|
+
VALUE v;
|
|
320
|
+
|
|
321
|
+
v = INT2FIX(str_to_int(at, length));
|
|
322
|
+
rb_ivar_set(parsed, id_via_sent_by_port, v);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
static void msg_via_branch(VALUE parsed, const char *at, size_t length)
|
|
327
|
+
{
|
|
328
|
+
TRACE();
|
|
329
|
+
VALUE v;
|
|
330
|
+
|
|
331
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
332
|
+
rb_ivar_set(parsed, id_via_branch, v);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
static void msg_via_branch_rfc3261(VALUE parsed, const char *at, size_t length)
|
|
337
|
+
{
|
|
338
|
+
TRACE();
|
|
339
|
+
|
|
340
|
+
rb_ivar_set(parsed, id_via_branch_rfc3261, Qtrue);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
static void msg_via_received(VALUE parsed, const char *at, size_t length)
|
|
345
|
+
{
|
|
346
|
+
TRACE();
|
|
347
|
+
VALUE v;
|
|
348
|
+
|
|
349
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
350
|
+
rb_ivar_set(parsed, id_via_received, v);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
static void msg_via_has_rport(VALUE parsed)
|
|
355
|
+
{
|
|
356
|
+
TRACE();
|
|
357
|
+
|
|
358
|
+
rb_ivar_set(parsed, id_via_has_rport, Qtrue);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
static void msg_via_has_alias(VALUE parsed)
|
|
363
|
+
{
|
|
364
|
+
TRACE();
|
|
365
|
+
|
|
366
|
+
rb_ivar_set(parsed, id_via_has_alias, Qtrue);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
static void msg_call_id(VALUE parsed, const char *at, size_t length)
|
|
371
|
+
{
|
|
372
|
+
TRACE();
|
|
373
|
+
VALUE v;
|
|
374
|
+
|
|
375
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
376
|
+
rb_ivar_set(parsed, id_call_id, v);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
static void msg_cseq_number(VALUE parsed, const char *at, size_t length)
|
|
381
|
+
{
|
|
382
|
+
TRACE();
|
|
383
|
+
VALUE v;
|
|
384
|
+
|
|
385
|
+
v = LONG2FIX(strtol(at,NULL,0));
|
|
386
|
+
rb_ivar_set(parsed, id_cseq, v);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
static void msg_max_forwards(VALUE parsed, const char *at, size_t length)
|
|
391
|
+
{
|
|
392
|
+
TRACE();
|
|
393
|
+
VALUE v;
|
|
394
|
+
|
|
395
|
+
v = INT2FIX(str_to_int(at, length));
|
|
396
|
+
rb_ivar_set(parsed, id_max_forwards, v);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
static void msg_content_length(VALUE parsed, const char *at, size_t length)
|
|
401
|
+
{
|
|
402
|
+
TRACE();
|
|
403
|
+
VALUE v;
|
|
404
|
+
|
|
405
|
+
v = LONG2FIX(strtol(at,NULL,0));
|
|
406
|
+
rb_ivar_set(parsed, id_content_length, v);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
static void msg_from_tag(VALUE parsed, const char *at, size_t length)
|
|
411
|
+
{
|
|
412
|
+
TRACE();
|
|
413
|
+
VALUE v;
|
|
414
|
+
|
|
415
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
416
|
+
rb_ivar_set(parsed, id_from_tag, v);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
static void msg_to_tag(VALUE parsed, const char *at, size_t length)
|
|
421
|
+
{
|
|
422
|
+
TRACE();
|
|
423
|
+
VALUE v;
|
|
424
|
+
|
|
425
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
426
|
+
rb_ivar_set(parsed, id_to_tag, v);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
static VALUE get_uri_object(VALUE parsed, enum uri_owner owner)
|
|
431
|
+
{
|
|
432
|
+
TRACE();
|
|
433
|
+
VALUE routes_array;
|
|
434
|
+
|
|
435
|
+
switch(owner) {
|
|
436
|
+
case uri_owner_ruri: return rb_ivar_get(parsed, id_ruri); break;
|
|
437
|
+
case uri_owner_from: return rb_ivar_get(parsed, id_from); break;
|
|
438
|
+
case uri_owner_to: return rb_ivar_get(parsed, id_to); break;
|
|
439
|
+
/* If we are in Route header, then return the last NameAddr entry. */
|
|
440
|
+
case uri_owner_route:
|
|
441
|
+
routes_array = rb_ivar_get(parsed, id_routes);
|
|
442
|
+
return RARRAY_PTR(routes_array)[RARRAY_LEN(routes_array)-1];
|
|
443
|
+
break;
|
|
444
|
+
case uri_owner_contact: return rb_ivar_get(parsed, id_contact); break;
|
|
445
|
+
}
|
|
446
|
+
return Qnil;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
static void uri_scheme(VALUE parsed, enum uri_owner owner, const char *at, size_t length, enum uri_scheme scheme)
|
|
451
|
+
{
|
|
452
|
+
TRACE();
|
|
453
|
+
VALUE v;
|
|
454
|
+
|
|
455
|
+
switch(scheme) {
|
|
456
|
+
case uri_scheme_sip: v = symbol_sip; break;
|
|
457
|
+
case uri_scheme_sips: v = symbol_sips; break;
|
|
458
|
+
case uri_scheme_tel: v = symbol_tel; break;
|
|
459
|
+
case uri_scheme_unknown: v = my_rb_str_downcase(at, length); break;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_scheme, v);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
static void uri_full(VALUE parsed, enum uri_owner owner, const char *at, size_t length, enum uri_scheme scheme)
|
|
467
|
+
{
|
|
468
|
+
TRACE();
|
|
469
|
+
VALUE v;
|
|
470
|
+
|
|
471
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
472
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri, v);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
static void uri_user(VALUE parsed, enum uri_owner owner, const char *at, size_t length, enum uri_scheme scheme)
|
|
477
|
+
{
|
|
478
|
+
TRACE();
|
|
479
|
+
VALUE v;
|
|
480
|
+
|
|
481
|
+
if (scheme == uri_scheme_tel)
|
|
482
|
+
v = my_rb_str_tel_number_clean(at, length);
|
|
483
|
+
else
|
|
484
|
+
v = my_rb_str_hex_unescape(at, length);
|
|
485
|
+
|
|
486
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_user, v);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
static void uri_host(VALUE parsed, enum uri_owner owner, const char *at, size_t length, int type)
|
|
491
|
+
{
|
|
492
|
+
TRACE();
|
|
493
|
+
VALUE v;
|
|
494
|
+
VALUE host_type;
|
|
495
|
+
|
|
496
|
+
/* If it's a domain and ends with ".", remove it. */
|
|
497
|
+
if (at[length-1] == '.')
|
|
498
|
+
length--;
|
|
499
|
+
|
|
500
|
+
/* Downcase the host part. */
|
|
501
|
+
v = my_rb_str_downcase(at, length);
|
|
502
|
+
|
|
503
|
+
switch(type) {
|
|
504
|
+
case host_type_domain: host_type = symbol_domain; break;
|
|
505
|
+
case host_type_ipv4: host_type = symbol_ipv4; break;
|
|
506
|
+
case host_type_ipv6: host_type = symbol_ipv6_reference; break;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* NOTE: In case of an IPv6 we normalize it so comparissons are easier later. */
|
|
510
|
+
if (host_type == symbol_ipv6_reference)
|
|
511
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_host, utils_normalize_ipv6(v, 0));
|
|
512
|
+
else
|
|
513
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_host, v);
|
|
514
|
+
|
|
515
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_host_type, host_type);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
static void uri_port(VALUE parsed, enum uri_owner owner, const char *at, size_t length, enum uri_scheme scheme)
|
|
520
|
+
{
|
|
521
|
+
TRACE();
|
|
522
|
+
VALUE v;
|
|
523
|
+
|
|
524
|
+
v = INT2FIX(str_to_int(at, length));
|
|
525
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_port, v);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
static void uri_param(VALUE parsed, enum uri_owner owner, const char *key, size_t key_len, const char *value, size_t value_len)
|
|
530
|
+
{
|
|
531
|
+
TRACE();
|
|
532
|
+
VALUE uri, params, v;
|
|
533
|
+
|
|
534
|
+
if ((uri = get_uri_object(parsed, owner)) == Qnil)
|
|
535
|
+
return;
|
|
536
|
+
|
|
537
|
+
if ((params = rb_ivar_get(uri, id_uri_params)) == Qnil) {
|
|
538
|
+
params = rb_hash_new();
|
|
539
|
+
rb_ivar_set(uri, id_uri_params, params);
|
|
540
|
+
}
|
|
541
|
+
if (value_len > 0)
|
|
542
|
+
v = RB_STR_UTF8_NEW(value, value_len);
|
|
543
|
+
else
|
|
544
|
+
v = Qnil;
|
|
545
|
+
rb_hash_aset(params, my_rb_str_downcase(key, key_len), v);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
static void uri_known_param(VALUE parsed, enum uri_owner owner, enum uri_param_name param_name, const char *at, size_t length, int param_value)
|
|
550
|
+
{
|
|
551
|
+
TRACE();
|
|
552
|
+
VALUE p, v;
|
|
553
|
+
|
|
554
|
+
switch(param_name) {
|
|
555
|
+
case uri_param_transport:
|
|
556
|
+
p = id_uri_transport_param;
|
|
557
|
+
switch(param_value) {
|
|
558
|
+
case transport_udp: v = symbol_udp; break;
|
|
559
|
+
case transport_tcp: v = symbol_tcp; break;
|
|
560
|
+
case transport_tls: v = symbol_tls; break;
|
|
561
|
+
case transport_sctp: v = symbol_sctp; break;
|
|
562
|
+
case transport_ws: v = symbol_ws; break;
|
|
563
|
+
case transport_wss: v = symbol_wss; break;
|
|
564
|
+
case transport_unknown: v = my_rb_str_downcase(at, length); break;
|
|
565
|
+
}
|
|
566
|
+
break;
|
|
567
|
+
case uri_param_ovid:
|
|
568
|
+
p = id_uri_ovid_param;
|
|
569
|
+
v = rb_str_new(at, length);
|
|
570
|
+
break;
|
|
571
|
+
case uri_tel_phone_context:
|
|
572
|
+
if (length == 0)
|
|
573
|
+
return;
|
|
574
|
+
/* If it's a domain and ends with ".", remove it. */
|
|
575
|
+
if (at[length-1] == '.')
|
|
576
|
+
length--;
|
|
577
|
+
p = id_uri_phone_context_param;
|
|
578
|
+
v = my_rb_str_downcase(at, length);
|
|
579
|
+
break;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
rb_ivar_set(get_uri_object(parsed, owner), p, v);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
static void uri_has_param(VALUE parsed, enum uri_owner owner, enum uri_param_name param_name)
|
|
587
|
+
{
|
|
588
|
+
TRACE();
|
|
589
|
+
|
|
590
|
+
VALUE p;
|
|
591
|
+
|
|
592
|
+
switch(param_name) {
|
|
593
|
+
case uri_param_lr: p = id_uri_lr_param; break;
|
|
594
|
+
case uri_param_ob: p = id_uri_ob_param; break;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
rb_ivar_set(get_uri_object(parsed, owner), p, Qtrue);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
static void uri_headers(VALUE parsed, enum uri_owner owner, const char *at, size_t length, enum uri_scheme scheme)
|
|
602
|
+
{
|
|
603
|
+
TRACE();
|
|
604
|
+
VALUE v;
|
|
605
|
+
|
|
606
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
607
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_uri_headers, v);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
static void uri_display_name(VALUE parsed, enum uri_owner owner, const char *at, size_t length, enum uri_scheme scheme)
|
|
612
|
+
{
|
|
613
|
+
TRACE();
|
|
614
|
+
VALUE v;
|
|
615
|
+
|
|
616
|
+
if (length == 0)
|
|
617
|
+
return;
|
|
618
|
+
|
|
619
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
620
|
+
rb_ivar_set(get_uri_object(parsed, owner), id_display_name, v);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
static void header_core_value(VALUE parsed, enum header_field header_field, const char *at, size_t length)
|
|
625
|
+
{
|
|
626
|
+
TRACE();
|
|
627
|
+
VALUE v;
|
|
628
|
+
|
|
629
|
+
if (length == 0)
|
|
630
|
+
return;
|
|
631
|
+
|
|
632
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
633
|
+
|
|
634
|
+
switch(header_field) {
|
|
635
|
+
case header_field_via: rb_ivar_set(parsed, id_via_core_value, v); break;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
static void header_param(VALUE parsed, enum header_field header_field, const char *key, size_t key_len, const char *value, size_t value_len)
|
|
641
|
+
{
|
|
642
|
+
TRACE();
|
|
643
|
+
VALUE v;
|
|
644
|
+
VALUE header_params;
|
|
645
|
+
|
|
646
|
+
switch(header_field) {
|
|
647
|
+
case header_field_via:
|
|
648
|
+
if ((header_params = rb_ivar_get(parsed, id_via_params)) == Qnil) {
|
|
649
|
+
header_params = rb_hash_new();
|
|
650
|
+
rb_ivar_set(parsed, id_via_params, header_params);
|
|
651
|
+
}
|
|
652
|
+
if (value_len > 0)
|
|
653
|
+
v = RB_STR_UTF8_NEW(value, value_len);
|
|
654
|
+
else
|
|
655
|
+
v = Qnil;
|
|
656
|
+
rb_hash_aset(header_params, my_rb_str_downcase(key, key_len), v);
|
|
657
|
+
break;
|
|
658
|
+
/* case header_field_contact:
|
|
659
|
+
if ((header_params = rb_ivar_get(parsed, id_contact_params)) == Qnil) {
|
|
660
|
+
header_params = rb_hash_new();
|
|
661
|
+
rb_ivar_set(parsed, id_contact_params, header_params);
|
|
662
|
+
}
|
|
663
|
+
if (value_len > 0)
|
|
664
|
+
v = RB_STR_UTF8_NEW(value, value_len);
|
|
665
|
+
else
|
|
666
|
+
v = Qnil;
|
|
667
|
+
rb_hash_aset(header_params, my_rb_str_downcase(key, key_len), v);
|
|
668
|
+
break; */
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
static void msg_contact_params(VALUE parsed, const char *at, size_t length)
|
|
674
|
+
{
|
|
675
|
+
TRACE();
|
|
676
|
+
VALUE v;
|
|
677
|
+
|
|
678
|
+
if (length == 0)
|
|
679
|
+
return;
|
|
680
|
+
|
|
681
|
+
v = RB_STR_UTF8_NEW(at, length);
|
|
682
|
+
rb_ivar_set(parsed, id_contact_params, v);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
static void option_tag(VALUE parsed, enum header_field header_field, const char *at, size_t length)
|
|
687
|
+
{
|
|
688
|
+
TRACE();
|
|
689
|
+
VALUE v;
|
|
690
|
+
VALUE id_option_tag_owner;
|
|
691
|
+
VALUE option_tag_owner;
|
|
692
|
+
|
|
693
|
+
switch(header_field) {
|
|
694
|
+
case header_field_require: id_option_tag_owner = id_require; break;
|
|
695
|
+
case header_field_proxy_require: id_option_tag_owner = id_proxy_require; break;
|
|
696
|
+
case header_field_supported: id_option_tag_owner = id_supported; break;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
if ((option_tag_owner = rb_ivar_get(parsed, id_option_tag_owner)) == Qnil) {
|
|
700
|
+
option_tag_owner = rb_ary_new();
|
|
701
|
+
rb_ivar_set(parsed, id_option_tag_owner, option_tag_owner);
|
|
702
|
+
}
|
|
703
|
+
rb_ary_push(option_tag_owner,my_rb_str_downcase(at, length));
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
/*************** Custom C funcions (helpers) ****************/
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
/*
|
|
711
|
+
* my_rb_str_tel_number_clean: Remove separators from a TEL URI number and downcase letters.
|
|
712
|
+
*/
|
|
713
|
+
static VALUE my_rb_str_tel_number_clean(const char *str, size_t len)
|
|
714
|
+
{
|
|
715
|
+
TRACE();
|
|
716
|
+
char *new_str;
|
|
717
|
+
VALUE str_clean;
|
|
718
|
+
|
|
719
|
+
new_str = ALLOC_N(char, len);
|
|
720
|
+
|
|
721
|
+
char *s;
|
|
722
|
+
int i, j;
|
|
723
|
+
int new_len;
|
|
724
|
+
|
|
725
|
+
for (s = (char *)str, i = 0, j = 0, new_len = len; i < len ; s++, i++)
|
|
726
|
+
/* The char is not a separator so keep it. */
|
|
727
|
+
if (*s != '-' && *s != '.' && *s != '(' && *s != ')')
|
|
728
|
+
/* Downcase if it's A-F. */
|
|
729
|
+
if (*s >= 'A' && *s <= 'F')
|
|
730
|
+
new_str[j++] = *s + 32;
|
|
731
|
+
else
|
|
732
|
+
new_str[j++] = *s;
|
|
733
|
+
else
|
|
734
|
+
new_len--;
|
|
735
|
+
|
|
736
|
+
str_clean = RB_STR_UTF8_NEW(new_str, new_len);
|
|
737
|
+
xfree(new_str);
|
|
738
|
+
return(str_clean);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
/*************** Ruby functions ****************/
|
|
744
|
+
|
|
745
|
+
static void SipMessageParser_free(void *parser)
|
|
746
|
+
{
|
|
747
|
+
TRACE();
|
|
748
|
+
if(parser) {
|
|
749
|
+
/* NOTE: Use always xfree() rather than free():
|
|
750
|
+
* http://www.mail-archive.com/libxml-devel@rubyforge.org/msg00242.html */
|
|
751
|
+
xfree(parser);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
VALUE SipMessageParser_alloc(VALUE klass)
|
|
757
|
+
{
|
|
758
|
+
TRACE();
|
|
759
|
+
VALUE obj;
|
|
760
|
+
/* NOTE: Use always ALLOC/ALLOC_N rather than malloc().
|
|
761
|
+
* ALLOC uses xmalloc:
|
|
762
|
+
* ALLOC(type) (type*)xmalloc(sizeof(type))
|
|
763
|
+
* ALLOC_N(type, n) (type*)xmalloc(sizeof(type)*(n))
|
|
764
|
+
*/
|
|
765
|
+
sip_message_parser *parser = ALLOC(sip_message_parser);
|
|
766
|
+
|
|
767
|
+
/* Asign functions to the pointers of sip_message_parser struct. */
|
|
768
|
+
parser->data_type = data_type;
|
|
769
|
+
parser->header = header;
|
|
770
|
+
|
|
771
|
+
parser->message.method = msg_method;
|
|
772
|
+
parser->message.status_code = msg_status_code;
|
|
773
|
+
parser->message.reason_phrase = msg_reason_phrase;
|
|
774
|
+
parser->message.sip_version = msg_sip_version;
|
|
775
|
+
parser->message.via_sent_by_host = msg_via_sent_by_host;
|
|
776
|
+
parser->message.via_sent_by_port = msg_via_sent_by_port;
|
|
777
|
+
parser->message.via_branch = msg_via_branch;
|
|
778
|
+
parser->message.via_branch_rfc3261 = msg_via_branch_rfc3261;
|
|
779
|
+
parser->message.via_received = msg_via_received;
|
|
780
|
+
parser->message.via_has_rport = msg_via_has_rport;
|
|
781
|
+
parser->message.via_has_alias = msg_via_has_alias;
|
|
782
|
+
parser->message.call_id = msg_call_id;
|
|
783
|
+
parser->message.cseq_number = msg_cseq_number;
|
|
784
|
+
parser->message.max_forwards = msg_max_forwards;
|
|
785
|
+
parser->message.content_length = msg_content_length;
|
|
786
|
+
parser->message.from_tag = msg_from_tag;
|
|
787
|
+
parser->message.to_tag = msg_to_tag;
|
|
788
|
+
parser->message.contact_params = msg_contact_params;
|
|
789
|
+
parser->message.header_core_value = header_core_value;
|
|
790
|
+
parser->message.header_param = header_param;
|
|
791
|
+
parser->message.option_tag = option_tag;
|
|
792
|
+
parser->message.init_component = init_component;
|
|
793
|
+
|
|
794
|
+
parser->uri.full = uri_full;
|
|
795
|
+
parser->uri.scheme = uri_scheme;
|
|
796
|
+
parser->uri.user = uri_user;
|
|
797
|
+
parser->uri.host = uri_host;
|
|
798
|
+
parser->uri.port = uri_port;
|
|
799
|
+
parser->uri.param = uri_param;
|
|
800
|
+
parser->uri.known_param = uri_known_param;
|
|
801
|
+
parser->uri.has_param = uri_has_param;
|
|
802
|
+
parser->uri.headers = uri_headers;
|
|
803
|
+
parser->uri.display_name = uri_display_name;
|
|
804
|
+
|
|
805
|
+
sip_message_parser_init(parser);
|
|
806
|
+
|
|
807
|
+
obj = Data_Wrap_Struct(klass, NULL, SipMessageParser_free, parser);
|
|
808
|
+
return obj;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* call-seq:
|
|
814
|
+
* parser.new -> parser
|
|
815
|
+
*
|
|
816
|
+
* Creates a new parser.
|
|
817
|
+
*/
|
|
818
|
+
VALUE SipMessageParser_init(VALUE self)
|
|
819
|
+
{
|
|
820
|
+
TRACE();
|
|
821
|
+
sip_message_parser *parser = NULL;
|
|
822
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
823
|
+
sip_message_parser_init(parser);
|
|
824
|
+
|
|
825
|
+
/* NOTE: This allows the C struct to access to the VALUE element of the Ruby
|
|
826
|
+
MessageParser instance. */
|
|
827
|
+
parser->ruby_sip_parser = self;
|
|
828
|
+
|
|
829
|
+
return self;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* call-seq:
|
|
835
|
+
* parser.reset -> nil
|
|
836
|
+
*
|
|
837
|
+
* Resets the parser to it's initial state so that you can reuse it
|
|
838
|
+
* rather than making new ones.
|
|
839
|
+
*/
|
|
840
|
+
VALUE SipMessageParser_reset(VALUE self)
|
|
841
|
+
{
|
|
842
|
+
TRACE();
|
|
843
|
+
sip_message_parser *parser = NULL;
|
|
844
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
845
|
+
sip_message_parser_init(parser);
|
|
846
|
+
|
|
847
|
+
return Qnil;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* call-seq:
|
|
853
|
+
* parser.finish -> true/false
|
|
854
|
+
*
|
|
855
|
+
* Finishes a parser early which could put in a "good" or bad state.
|
|
856
|
+
* You should call reset after finish it or bad things will happen.
|
|
857
|
+
*/
|
|
858
|
+
VALUE SipMessageParser_finish(VALUE self)
|
|
859
|
+
{
|
|
860
|
+
TRACE();
|
|
861
|
+
sip_message_parser *parser = NULL;
|
|
862
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
863
|
+
sip_message_parser_finish(parser);
|
|
864
|
+
|
|
865
|
+
return sip_message_parser_is_finished(parser) ? Qtrue : Qfalse;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* call-seq:
|
|
871
|
+
* parser.execute(buffer, start) -> Integer
|
|
872
|
+
*/
|
|
873
|
+
VALUE SipMessageParser_execute(VALUE self, VALUE buffer, VALUE start)
|
|
874
|
+
{
|
|
875
|
+
TRACE();
|
|
876
|
+
sip_message_parser *parser = NULL;
|
|
877
|
+
int from = 0;
|
|
878
|
+
char *dptr = NULL;
|
|
879
|
+
long dlen = 0;
|
|
880
|
+
|
|
881
|
+
REQUIRE_TYPE(buffer, T_STRING);
|
|
882
|
+
REQUIRE_TYPE(start, T_FIXNUM);
|
|
883
|
+
|
|
884
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
885
|
+
|
|
886
|
+
from = FIX2INT(start);
|
|
887
|
+
dptr = RSTRING_PTR(buffer);
|
|
888
|
+
dlen = RSTRING_LEN(buffer);
|
|
889
|
+
|
|
890
|
+
/* This should never occur or there is an error in the parser. */
|
|
891
|
+
if(from >= dlen)
|
|
892
|
+
rb_raise(eSIPMessageParserError, "requested start is after buffer end.");
|
|
893
|
+
|
|
894
|
+
sip_message_parser_execute(parser, dptr, dlen, from);
|
|
895
|
+
|
|
896
|
+
if(sip_message_parser_has_error(parser))
|
|
897
|
+
return Qfalse;
|
|
898
|
+
else
|
|
899
|
+
return INT2FIX(sip_message_parser_nread(parser));
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* call-seq:
|
|
905
|
+
* parser.error? -> true/false
|
|
906
|
+
*
|
|
907
|
+
* Tells you whether the parser is in an error state.
|
|
908
|
+
*/
|
|
909
|
+
VALUE SipMessageParser_has_error(VALUE self)
|
|
910
|
+
{
|
|
911
|
+
TRACE();
|
|
912
|
+
sip_message_parser *parser = NULL;
|
|
913
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
914
|
+
|
|
915
|
+
return sip_message_parser_has_error(parser) ? Qtrue : Qfalse;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* call-seq:
|
|
921
|
+
* parser.error -> String
|
|
922
|
+
*
|
|
923
|
+
* Returns a String showing the error by enclosing the exact wrong char between {{{ }}}.
|
|
924
|
+
*/
|
|
925
|
+
VALUE SipMessageParser_error(VALUE self)
|
|
926
|
+
{
|
|
927
|
+
TRACE();
|
|
928
|
+
sip_message_parser *parser = NULL;
|
|
929
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
930
|
+
|
|
931
|
+
if(sip_message_parser_has_error(parser)) {
|
|
932
|
+
char *parsing_error_str;
|
|
933
|
+
int parsing_error_str_len;
|
|
934
|
+
int i;
|
|
935
|
+
int j;
|
|
936
|
+
VALUE rb_error_str;
|
|
937
|
+
|
|
938
|
+
/* Duplicate error string length so '\r' and '\n' are displayed as CR and LF.
|
|
939
|
+
Let 6 chars more for allocating {{{ and }}}. */
|
|
940
|
+
parsing_error_str = ALLOC_N(char, 2*parser->error_len + 6);
|
|
941
|
+
|
|
942
|
+
parsing_error_str_len=0;
|
|
943
|
+
for(i=0, j=0; i < parser->error_len; i++) {
|
|
944
|
+
if (i != parser->error_pos) {
|
|
945
|
+
if (parser->error_start[i] == '\r') {
|
|
946
|
+
parsing_error_str[j++] = '\\';
|
|
947
|
+
parsing_error_str[j++] = 'r';
|
|
948
|
+
parsing_error_str_len += 2;
|
|
949
|
+
}
|
|
950
|
+
else if (parser->error_start[i] == '\n') {
|
|
951
|
+
parsing_error_str[j++] = '\\';
|
|
952
|
+
parsing_error_str[j++] = 'n';
|
|
953
|
+
parsing_error_str_len += 2;
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
parsing_error_str[j++] = parser->error_start[i];
|
|
957
|
+
parsing_error_str_len++;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
parsing_error_str[j++] = '{';
|
|
962
|
+
parsing_error_str[j++] = '{';
|
|
963
|
+
parsing_error_str[j++] = '{';
|
|
964
|
+
if (parser->error_start[i] == '\r') {
|
|
965
|
+
parsing_error_str[j++] = '\\';
|
|
966
|
+
parsing_error_str[j++] = 'r';
|
|
967
|
+
parsing_error_str_len += 2;
|
|
968
|
+
}
|
|
969
|
+
else if (parser->error_start[i] == '\n') {
|
|
970
|
+
parsing_error_str[j++] = '\\';
|
|
971
|
+
parsing_error_str[j++] = 'n';
|
|
972
|
+
parsing_error_str_len += 2;
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
parsing_error_str[j++] = parser->error_start[i];
|
|
976
|
+
parsing_error_str_len++;
|
|
977
|
+
}
|
|
978
|
+
parsing_error_str[j++] = '}';
|
|
979
|
+
parsing_error_str[j++] = '}';
|
|
980
|
+
parsing_error_str[j++] = '}';
|
|
981
|
+
parsing_error_str_len += 6;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
rb_error_str = rb_str_new(parsing_error_str, parsing_error_str_len);
|
|
986
|
+
xfree(parsing_error_str);
|
|
987
|
+
return rb_error_str;
|
|
988
|
+
}
|
|
989
|
+
else
|
|
990
|
+
return Qnil;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* call-seq:
|
|
996
|
+
* parser.finished? -> true/false
|
|
997
|
+
*
|
|
998
|
+
* Tells you whether the parser is finished or not and in a good state.
|
|
999
|
+
*/
|
|
1000
|
+
VALUE SipMessageParser_is_finished(VALUE self)
|
|
1001
|
+
{
|
|
1002
|
+
TRACE();
|
|
1003
|
+
sip_message_parser *parser = NULL;
|
|
1004
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
1005
|
+
|
|
1006
|
+
return sip_message_parser_is_finished(parser) ? Qtrue : Qfalse;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* call-seq:
|
|
1012
|
+
* parser.parsed -> OverSIP::Request or OverSIP::Response or :outbound_keepalive or nil
|
|
1013
|
+
*
|
|
1014
|
+
* Returns the parsed object. It doesn't meant that the parsing has succedded. The returned
|
|
1015
|
+
* object could be a message identified as a Request or Response or :outbound_keepalive, but later
|
|
1016
|
+
* the message has been detected as invalid. So the parsed object is incomplete.
|
|
1017
|
+
*
|
|
1018
|
+
* In case the parsing has failed in the first char the method returns nil.
|
|
1019
|
+
*/
|
|
1020
|
+
VALUE SipMessageParser_parsed(VALUE self)
|
|
1021
|
+
{
|
|
1022
|
+
TRACE();
|
|
1023
|
+
sip_message_parser *parser = NULL;
|
|
1024
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
1025
|
+
|
|
1026
|
+
/* NOTE: We can safely access here to parser->parsed as its content is also referenced
|
|
1027
|
+
* by id_parsed so it cannot be garbage collected while the OverSIP::MessageParser
|
|
1028
|
+
* still alives. */
|
|
1029
|
+
return parser->parsed;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* call-seq:
|
|
1035
|
+
* parser.nread -> Integer
|
|
1036
|
+
*
|
|
1037
|
+
* Returns the amount of data processed so far during this processing cycle. It is
|
|
1038
|
+
* set to 0 on initialize or reset calls and is incremented each time execute is called.
|
|
1039
|
+
*/
|
|
1040
|
+
VALUE SipMessageParser_nread(VALUE self)
|
|
1041
|
+
{
|
|
1042
|
+
TRACE();
|
|
1043
|
+
sip_message_parser *parser = NULL;
|
|
1044
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
1045
|
+
|
|
1046
|
+
return INT2FIX(parser->nread);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* call-seq:
|
|
1052
|
+
* parser.duplicated_core_header? -> true/false
|
|
1053
|
+
*
|
|
1054
|
+
* In case a core header is duplicated its name is returned as string.
|
|
1055
|
+
* False otherwise.
|
|
1056
|
+
*/
|
|
1057
|
+
VALUE SipMessageParser_has_duplicated_core_header(VALUE self)
|
|
1058
|
+
{
|
|
1059
|
+
TRACE();
|
|
1060
|
+
sip_message_parser *parser = NULL;
|
|
1061
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
1062
|
+
|
|
1063
|
+
/* NOTE: Good moment for counting the num of Via values and store it. */
|
|
1064
|
+
rb_ivar_set(parser->parsed, id_num_vias, INT2FIX(parser->num_via));
|
|
1065
|
+
|
|
1066
|
+
if (parser->num_from > 1)
|
|
1067
|
+
return string_From;
|
|
1068
|
+
else if (parser->num_to > 1)
|
|
1069
|
+
return string_To;
|
|
1070
|
+
else if (parser->num_cseq > 1)
|
|
1071
|
+
return string_CSeq;
|
|
1072
|
+
else if (parser->num_call_id > 1)
|
|
1073
|
+
return string_Call_ID;
|
|
1074
|
+
else if (parser->num_max_forwards > 1)
|
|
1075
|
+
return string_Max_Forwards;
|
|
1076
|
+
else if (parser->num_content_length > 1)
|
|
1077
|
+
return string_Content_Length;
|
|
1078
|
+
|
|
1079
|
+
return Qfalse;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* call-seq:
|
|
1085
|
+
* parser.missing_core_header? -> true/false
|
|
1086
|
+
*
|
|
1087
|
+
* In case a core header is missing its name is returned as string.
|
|
1088
|
+
* False otherwise.
|
|
1089
|
+
*/
|
|
1090
|
+
VALUE SipMessageParser_has_missing_core_header(VALUE self)
|
|
1091
|
+
{
|
|
1092
|
+
TRACE();
|
|
1093
|
+
sip_message_parser *parser = NULL;
|
|
1094
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
1095
|
+
|
|
1096
|
+
if (parser->num_via == 0)
|
|
1097
|
+
return string_Via;
|
|
1098
|
+
else if (parser->num_from == 0)
|
|
1099
|
+
return string_From;
|
|
1100
|
+
else if (parser->num_to == 0)
|
|
1101
|
+
return string_To;
|
|
1102
|
+
else if (parser->num_cseq == 0)
|
|
1103
|
+
return string_CSeq;
|
|
1104
|
+
else if (parser->num_call_id == 0)
|
|
1105
|
+
return string_Call_ID;
|
|
1106
|
+
|
|
1107
|
+
return Qfalse;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
VALUE SipMessageParser_post_parsing(VALUE self)
|
|
1112
|
+
{
|
|
1113
|
+
TRACE();
|
|
1114
|
+
sip_message_parser *parser = NULL;
|
|
1115
|
+
DATA_GET(self, sip_message_parser, parser);
|
|
1116
|
+
|
|
1117
|
+
/* We just parse Contact if it's a single header with a single Name Addr within it. */
|
|
1118
|
+
if (! (parser->contact_is_valid == 1 && parser->num_contact == 1)) {
|
|
1119
|
+
/*printf("--- if (! (parser->contact_is_valid == 1 && parser->num_contact == 1)) returns false\n");
|
|
1120
|
+
printf("--- parser->num_contact = %d\n", parser->num_contact);*/
|
|
1121
|
+
rb_ivar_set(parser->parsed, id_contact, Qnil);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
return Qnil;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* call-seq:
|
|
1130
|
+
* OverSIP::SIP::MessageParser.headarize -> String
|
|
1131
|
+
*
|
|
1132
|
+
* Tries to lookup the header name in a list of well-known headers. If so,
|
|
1133
|
+
* returns the retrieved VALUE. It also works for short headers.
|
|
1134
|
+
* In case the header is unknown, it normalizes it (by capitalizing the
|
|
1135
|
+
* first letter and each letter under a "-" or "_" symbol).
|
|
1136
|
+
*/
|
|
1137
|
+
VALUE SipMessageParser_Class_headerize(VALUE self, VALUE string)
|
|
1138
|
+
{
|
|
1139
|
+
TRACE();
|
|
1140
|
+
if (TYPE(string) != T_STRING)
|
|
1141
|
+
rb_raise(rb_eTypeError, "Argument must be a String");
|
|
1142
|
+
|
|
1143
|
+
if ((RSTRING_LEN(string)) == 0)
|
|
1144
|
+
rb_str_new(RSTRING_PTR(string), RSTRING_LEN(string));
|
|
1145
|
+
|
|
1146
|
+
return(headerize(RSTRING_PTR(string), RSTRING_LEN(string)));
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
void Init_sip_parser()
|
|
1153
|
+
{
|
|
1154
|
+
TRACE();
|
|
1155
|
+
|
|
1156
|
+
mOverSIP = rb_define_module("OverSIP");
|
|
1157
|
+
eOverSIPError = rb_define_class_under(mOverSIP, "Error", rb_eStandardError);
|
|
1158
|
+
|
|
1159
|
+
mSIP = rb_define_module_under(mOverSIP, "SIP");
|
|
1160
|
+
cSIPMessageParser = rb_define_class_under(mSIP, "MessageParser", rb_cObject);
|
|
1161
|
+
cSIPMessage = rb_define_class_under(mSIP, "Message", rb_cObject);
|
|
1162
|
+
cSIPRequest = rb_define_class_under(mSIP, "Request", cSIPMessage);
|
|
1163
|
+
cSIPResponse = rb_define_class_under(mSIP, "Response", cSIPMessage);
|
|
1164
|
+
cUri = rb_define_class_under(mSIP, "Uri", rb_cObject);
|
|
1165
|
+
cNameAddr = rb_define_class_under(mSIP, "NameAddr", cUri);
|
|
1166
|
+
eSIPMessageParserError = rb_define_class_under(mSIP, "MessageParserError", eOverSIPError);
|
|
1167
|
+
|
|
1168
|
+
rb_define_alloc_func(cSIPMessageParser, SipMessageParser_alloc);
|
|
1169
|
+
rb_define_method(cSIPMessageParser, "initialize", SipMessageParser_init,0);
|
|
1170
|
+
rb_define_method(cSIPMessageParser, "reset", SipMessageParser_reset,0);
|
|
1171
|
+
rb_define_method(cSIPMessageParser, "finish", SipMessageParser_finish,0);
|
|
1172
|
+
rb_define_method(cSIPMessageParser, "execute", SipMessageParser_execute,2);
|
|
1173
|
+
rb_define_method(cSIPMessageParser, "error?", SipMessageParser_has_error,0);
|
|
1174
|
+
rb_define_method(cSIPMessageParser, "error", SipMessageParser_error,0);
|
|
1175
|
+
rb_define_method(cSIPMessageParser, "finished?", SipMessageParser_is_finished,0);
|
|
1176
|
+
rb_define_method(cSIPMessageParser, "parsed", SipMessageParser_parsed,0);
|
|
1177
|
+
rb_define_method(cSIPMessageParser, "nread", SipMessageParser_nread,0);
|
|
1178
|
+
rb_define_method(cSIPMessageParser, "duplicated_core_header?", SipMessageParser_has_duplicated_core_header,0);
|
|
1179
|
+
rb_define_method(cSIPMessageParser, "missing_core_header?", SipMessageParser_has_missing_core_header,0);
|
|
1180
|
+
rb_define_method(cSIPMessageParser, "post_parsing", SipMessageParser_post_parsing,0);
|
|
1181
|
+
|
|
1182
|
+
rb_define_module_function(cSIPMessageParser, "headerize", SipMessageParser_Class_headerize,1);
|
|
1183
|
+
|
|
1184
|
+
init_common_headers();
|
|
1185
|
+
init_short_headers();
|
|
1186
|
+
|
|
1187
|
+
id_headers = rb_intern("@headers");
|
|
1188
|
+
id_parsed = rb_intern("@parsed");
|
|
1189
|
+
id_sip_method = rb_intern("@sip_method");
|
|
1190
|
+
id_is_unknown_method = rb_intern("@is_unknown_method");
|
|
1191
|
+
id_ruri = rb_intern("@ruri");
|
|
1192
|
+
id_status_code = rb_intern("@status_code");
|
|
1193
|
+
id_reason_phrase = rb_intern("@reason_phrase");
|
|
1194
|
+
id_sip_version = rb_intern("@sip_version");
|
|
1195
|
+
id_via_sent_by_host = rb_intern("@via_sent_by_host");
|
|
1196
|
+
id_via_sent_by_port = rb_intern("@via_sent_by_port");
|
|
1197
|
+
id_via_branch = rb_intern("@via_branch");
|
|
1198
|
+
id_via_branch_rfc3261 = rb_intern("@via_branch_rfc3261");
|
|
1199
|
+
id_via_received = rb_intern("@via_received");
|
|
1200
|
+
id_via_has_rport = rb_intern("@via_has_rport");
|
|
1201
|
+
id_via_has_alias = rb_intern("@via_has_alias");
|
|
1202
|
+
id_via_core_value = rb_intern("@via_core_value");
|
|
1203
|
+
id_via_params = rb_intern("@via_params");
|
|
1204
|
+
id_num_vias = rb_intern("@num_vias");
|
|
1205
|
+
id_call_id = rb_intern("@call_id");
|
|
1206
|
+
id_cseq = rb_intern("@cseq");
|
|
1207
|
+
id_max_forwards = rb_intern("@max_forwards");
|
|
1208
|
+
id_content_length = rb_intern("@content_length");
|
|
1209
|
+
id_from = rb_intern("@from");
|
|
1210
|
+
id_from_tag = rb_intern("@from_tag");
|
|
1211
|
+
id_to = rb_intern("@to");
|
|
1212
|
+
id_to_tag = rb_intern("@to_tag");
|
|
1213
|
+
id_routes = rb_intern("@routes");
|
|
1214
|
+
id_contact = rb_intern("@contact");
|
|
1215
|
+
id_contact_params = rb_intern("@contact_params");
|
|
1216
|
+
id_require = rb_intern("@require");
|
|
1217
|
+
id_proxy_require = rb_intern("@proxy_require");
|
|
1218
|
+
id_supported = rb_intern("@supported");
|
|
1219
|
+
id_hdr_via = rb_intern("@hdr_via");
|
|
1220
|
+
id_hdr_from = rb_intern("@hdr_from");
|
|
1221
|
+
id_hdr_to = rb_intern("@hdr_to");
|
|
1222
|
+
id_hdr_route = rb_intern("@hdr_route");
|
|
1223
|
+
|
|
1224
|
+
id_display_name = rb_intern("@display_name");
|
|
1225
|
+
id_uri = rb_intern("@uri");
|
|
1226
|
+
id_uri_scheme = rb_intern("@scheme");
|
|
1227
|
+
id_uri_user = rb_intern("@user");
|
|
1228
|
+
id_uri_host = rb_intern("@host");
|
|
1229
|
+
id_uri_host_type = rb_intern("@host_type");
|
|
1230
|
+
id_uri_port = rb_intern("@port");
|
|
1231
|
+
id_uri_params = rb_intern("@params");
|
|
1232
|
+
id_uri_transport_param = rb_intern("@transport_param");
|
|
1233
|
+
id_uri_lr_param = rb_intern("@lr_param");
|
|
1234
|
+
id_uri_ob_param = rb_intern("@ob_param");
|
|
1235
|
+
id_uri_ovid_param = rb_intern("@ovid_param");
|
|
1236
|
+
id_uri_phone_context_param = rb_intern("@phone_context_param");
|
|
1237
|
+
id_uri_headers = rb_intern("@headers");
|
|
1238
|
+
|
|
1239
|
+
symbol_outbound_keepalive = ID2SYM(rb_intern("outbound_keepalive"));
|
|
1240
|
+
symbol_INVITE = ID2SYM(rb_intern("INVITE"));
|
|
1241
|
+
symbol_ACK = ID2SYM(rb_intern("ACK"));
|
|
1242
|
+
symbol_CANCEL = ID2SYM(rb_intern("CANCEL"));
|
|
1243
|
+
symbol_PRACK = ID2SYM(rb_intern("PRACK"));
|
|
1244
|
+
symbol_BYE = ID2SYM(rb_intern("BYE"));
|
|
1245
|
+
symbol_REFER = ID2SYM(rb_intern("REFER"));
|
|
1246
|
+
symbol_INFO = ID2SYM(rb_intern("INFO"));
|
|
1247
|
+
symbol_UPDATE = ID2SYM(rb_intern("UPDATE"));
|
|
1248
|
+
symbol_OPTIONS = ID2SYM(rb_intern("OPTIONS"));
|
|
1249
|
+
symbol_REGISTER = ID2SYM(rb_intern("REGISTER"));
|
|
1250
|
+
symbol_MESSAGE = ID2SYM(rb_intern("MESSAGE"));
|
|
1251
|
+
symbol_SUBSCRIBE = ID2SYM(rb_intern("SUBSCRIBE"));
|
|
1252
|
+
symbol_NOTIFY = ID2SYM(rb_intern("NOTIFY"));
|
|
1253
|
+
symbol_PUBLISH = ID2SYM(rb_intern("PUBLISH"));
|
|
1254
|
+
symbol_PULL = ID2SYM(rb_intern("PULL"));
|
|
1255
|
+
symbol_PUSH = ID2SYM(rb_intern("PUSH"));
|
|
1256
|
+
symbol_STORE = ID2SYM(rb_intern("STORE"));
|
|
1257
|
+
symbol_sip = ID2SYM(rb_intern("sip"));
|
|
1258
|
+
symbol_sips = ID2SYM(rb_intern("sips"));
|
|
1259
|
+
symbol_tel = ID2SYM(rb_intern("tel"));
|
|
1260
|
+
symbol_udp = ID2SYM(rb_intern("udp"));
|
|
1261
|
+
symbol_tcp = ID2SYM(rb_intern("tcp"));
|
|
1262
|
+
symbol_tls = ID2SYM(rb_intern("tls"));
|
|
1263
|
+
symbol_sctp = ID2SYM(rb_intern("sctp"));
|
|
1264
|
+
symbol_ws = ID2SYM(rb_intern("ws"));
|
|
1265
|
+
symbol_wss = ID2SYM(rb_intern("wss"));
|
|
1266
|
+
symbol_domain = ID2SYM(rb_intern("domain"));
|
|
1267
|
+
symbol_ipv4 = ID2SYM(rb_intern("ipv4"));
|
|
1268
|
+
symbol_ipv6 = ID2SYM(rb_intern("ipv6"));
|
|
1269
|
+
symbol_ipv6_reference = ID2SYM(rb_intern("ipv6_reference"));
|
|
1270
|
+
|
|
1271
|
+
string_Via = rb_str_new2("Via");
|
|
1272
|
+
string_Via = rb_obj_freeze(string_Via);
|
|
1273
|
+
rb_global_variable(&string_Via);
|
|
1274
|
+
string_From = rb_str_new2("From");
|
|
1275
|
+
string_From = rb_obj_freeze(string_From);
|
|
1276
|
+
rb_global_variable(&string_From);
|
|
1277
|
+
string_To = rb_str_new2("To");
|
|
1278
|
+
string_To = rb_obj_freeze(string_To);
|
|
1279
|
+
rb_global_variable(&string_To);
|
|
1280
|
+
string_CSeq = rb_str_new2("CSeq");
|
|
1281
|
+
string_CSeq = rb_obj_freeze(string_CSeq);
|
|
1282
|
+
rb_global_variable(&string_CSeq);
|
|
1283
|
+
string_Call_ID = rb_str_new2("Call-ID");
|
|
1284
|
+
string_Call_ID = rb_obj_freeze(string_Call_ID);
|
|
1285
|
+
rb_global_variable(&string_Call_ID);
|
|
1286
|
+
string_Max_Forwards = rb_str_new2("Max-Forwards");
|
|
1287
|
+
string_Max_Forwards = rb_obj_freeze(string_Max_Forwards);
|
|
1288
|
+
rb_global_variable(&string_Max_Forwards);
|
|
1289
|
+
string_Content_Length = rb_str_new2("Content-Length");
|
|
1290
|
+
string_Content_Length = rb_obj_freeze(string_Content_Length);
|
|
1291
|
+
rb_global_variable(&string_Content_Length);
|
|
1292
|
+
}
|