oversip 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -1,7 +1,10 @@
1
- The MIT LICENSE
2
-
1
+ Name: OverSIP
2
+ Maintainer: Iñaki Baz Castillo <ibc@aliax.net>
3
3
  Copyright (c) 2012 Iñaki Baz Castillo <ibc@aliax.net>
4
4
 
5
+
6
+ License: The MIT LICENSE
7
+
5
8
  Permission is hereby granted, free of charge, to any person obtaining
6
9
  a copy of this software and associated documentation files (the
7
10
  "Software"), to deal in the Software without restriction, including
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  OverSIP
2
2
  =======
3
3
 
4
- **UNDER CONSTRUCTION:** please wait a bit...
4
+ **WEB UNDER CONSTRUCTION:** The code is stable and working. This web page and documentation is not... please wait a bit.
5
5
 
6
6
  OverSIP is an async SIP proxy/server programmable in Ruby language.
7
7
 
data/Rakefile CHANGED
@@ -33,7 +33,7 @@ file "bin/oversip_stud" => "tmp" do
33
33
  FileUtils.remove_dir "tmp"
34
34
  end
35
35
  CLEAN.include("ext/stud/Makefile")
36
- CLEAN.include("ext/stud/mkmf.log")
36
+ CLEAN.include("thirdparty/stud/mkmf.log")
37
37
  CLEAN.include("bin/oversip_stud")
38
38
 
39
39
 
data/debian/changelog ADDED
@@ -0,0 +1,5 @@
1
+ oversip (1.0.0) stable; urgency=low
2
+
3
+ * Initial release.
4
+
5
+ -- Iñaki Baz Castillo <ibc@aliax.net> Mon, 09 Jul 2012 21:21:00 +0100
data/debian/compat ADDED
@@ -0,0 +1 @@
1
+ 7
data/debian/control ADDED
@@ -0,0 +1,25 @@
1
+ Source: oversip
2
+ Section: comm
3
+ Priority: optional
4
+ Maintainer: Iñaki Baz Castillo <ibc@aliax.net>
5
+ Homepage: http://www.oversip.net
6
+ Build-Depends: debhelper (>= 7)
7
+ Standards-Version: 3.9.3
8
+
9
+ Package: oversip
10
+ Architecture: all
11
+ Depends: ${shlibs:Depends}, ${misc:Depends}, ruby1.9.1, ruby1.9.1-dev, make, g++, libssl-dev, libev-dev
12
+ Recommends: unbound
13
+ Description: OverSIP (the SIP dreams factory) is an async SIP proxy/server programmable in Ruby language.
14
+ Some features of OverSIP are:
15
+ - SIP transports: UDP, TCP, TLS and WebSocket.
16
+ - Full IPv4 and IPv6 support.
17
+ - RFC 3263: SIP DNS mechanism (NAPTR, SRV, A, AAAA) for failover and load
18
+ balancing based on DNS.
19
+ - RFC 5626: OverSIP is a perfect Outbound EDGE proxy, including an integrated
20
+ STUN server.
21
+ - Fully programmable in Ruby language (make SIP easy).
22
+ - Fast and efficient: OverSIP core is coded in C language.
23
+ OverSIP is build on top of EventMachine async library which follows the Reactor
24
+ Pattern design, allowing thousands of concurrent connections and requests in a
25
+ never-blocking fashion.
data/debian/copyright ADDED
@@ -0,0 +1,25 @@
1
+ Name: OverSIP
2
+ Maintainer: Iñaki Baz Castillo <ibc@aliax.net>
3
+ Copyright (c) 2012 Iñaki Baz Castillo <ibc@aliax.net>
4
+
5
+
6
+ License: The MIT LICENSE
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ "Software"), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ #
2
+ # oversip startup options
3
+ #
4
+
5
+ # Set to 'yes' when configured.
6
+ RUN=no
7
+
8
+ # User to run as.
9
+ USER=oversip
10
+
11
+ # Group to run as.
12
+ GROUP=oversip
@@ -0,0 +1,203 @@
1
+ #! /bin/bash
2
+
3
+ ### BEGIN INIT INFO
4
+ # Provides: oversip
5
+ # Required-Start: $syslog $network $remote_fs
6
+ # Required-Stop: $syslog $network $remote_fs
7
+ # Default-Start: 2 3 4 5
8
+ # Default-Stop: 0 1 6
9
+ # Short-Description: Start/stop OverSIP
10
+ # Description: Start/stop OverSIP
11
+ ### END INIT INFO
12
+
13
+ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/var/lib/gems/1.9.1/bin
14
+ NAME=oversip
15
+ DESC=OverSIP
16
+ HOMEDIR=/var/run/$NAME
17
+ PIDFILE_NAME=$NAME.pid
18
+ RUN=no
19
+ RUBY_GEM=$NAME
20
+ RUBY_EXE=ruby1.9.1
21
+
22
+
23
+ . /lib/lsb/init-functions
24
+
25
+ # Debian LSB functions don't add \n in function log_begin_msg().
26
+ # In Ubuntu such function is overriden in /etc/lsb-base-logging.sh.
27
+ UBUNTU_LOGGING=0
28
+ [ -r /etc/lsb-base-logging.sh ] && UBUNTU_LOGGING=1
29
+
30
+ [ -r /etc/default/$NAME ] && . /etc/default/$NAME
31
+
32
+ # Ensure Ruby executable is installed.
33
+ which $RUBY_EXE >/dev/null
34
+ if [ $? -ne 0 ] ; then
35
+ log_failure_msg "ruby1.9.1 is not installed, exiting."
36
+ log_end_msg 5
37
+ exit 5
38
+ fi
39
+
40
+ # Check whether OverSIP Ruby Gem is installed and get the executable location.
41
+ DAEMON=$(which $NAME)
42
+ if [ $? -ne 0 ] ; then
43
+ log_failure_msg "$DESC ($NAME): Ruby Gem '$RUBY_GEM' is not installed, exiting."
44
+
45
+ case "$1" in
46
+ status)
47
+ # LSB - 4: program or service status is unknown.
48
+ log_end_msg 4
49
+ exit 4
50
+ ;;
51
+ *)
52
+ # LSB - 5: program is not installed.
53
+ log_end_msg 5
54
+ exit 5
55
+ ;;
56
+ esac
57
+ fi
58
+
59
+ if [ ! -x $DAEMON ]; then
60
+ log_failure_msg "$DESC ($NAME): executable '$DAEMON' does not exist or has not execution access. It should be provided by Ruby Gem '$RUBY_GEM'."
61
+
62
+ case "$1" in
63
+ status)
64
+ # LSB - 4: program or service status is unknown.
65
+ log_end_msg 4
66
+ exit 4
67
+ ;;
68
+ *)
69
+ # LSB - 5: program is not installed.
70
+ log_end_msg 5
71
+ exit 5
72
+ ;;
73
+ esac
74
+ fi
75
+
76
+ if [ "$RUN" != "yes" ] ; then
77
+ log_failure_msg "$DESC ($NAME) not yet configured. Set RUN=yes in /etc/default/$NAME."
78
+ exit 0
79
+ fi
80
+
81
+ PIDFILE="${HOMEDIR}/${PIDFILE_NAME}"
82
+ OPTIONS="-P ${PIDFILE}"
83
+ if [ -n "$USER" ] ; then
84
+ OPTIONS="${OPTIONS} -u ${USER}"
85
+ fi
86
+ if [ -n "$GROUP" ] ; then
87
+ OPTIONS="${OPTIONS} -g ${GROUP}"
88
+ fi
89
+
90
+
91
+ check_homedir ()
92
+ {
93
+ # Create HOMEDIR directory in case it doesn't exist.
94
+ # Useful in Ubuntu as /var/run/ content is deleted in shutdown.
95
+ if [ ! -d $HOMEDIR ] ; then mkdir $HOMEDIR ; fi
96
+
97
+ # Set the appropiate owner and group
98
+ if [ -n "$USER" ] ; then chown ${USER} $HOMEDIR ; fi
99
+ if [ -n "$GROUP" ] ; then chgrp ${GROUP} $HOMEDIR ; fi
100
+ }
101
+
102
+
103
+ start() {
104
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --quiet \
105
+ --exec $DAEMON -- $OPTIONS
106
+ res=$?
107
+
108
+ if [ $res -eq 0 ] ; then
109
+ log_end_msg 0
110
+ exit 0
111
+ else
112
+ if [ ! -r "$PIDFILE" ]; then
113
+ log_failure_msg "error, failed to start."
114
+ log_end_msg 1
115
+ exit 1
116
+ elif read pid < "$PIDFILE" && ps -p "$pid" > /dev/null 2>&1; then
117
+ log_warning_msg "already running."
118
+ exit 0
119
+ else
120
+ log_failure_msg "error, failed to start (and PID file '$PIDFILE' exists)."
121
+ log_end_msg 1
122
+ exit 1
123
+ fi
124
+ fi
125
+ }
126
+
127
+
128
+ set -e
129
+
130
+ case "$1" in
131
+
132
+ start)
133
+ check_homedir
134
+ log_daemon_msg "Starting $DESC ($NAME)"
135
+ echo
136
+ set +e
137
+
138
+ start
139
+ ;;
140
+
141
+ stop)
142
+ log_daemon_msg "Stopping $DESC ($NAME)"
143
+ echo
144
+ set +e
145
+
146
+ start-stop-daemon --oknodo --stop --pidfile $PIDFILE --quiet \
147
+ --name $NAME
148
+ res=$?
149
+
150
+ # Posix MQueue for syslogging is created with owner root (to ensure
151
+ # rlimits and so) so it cannot be deleted by $USER when stopping the
152
+ # server. This command removes the mqueue when performing the "stop"
153
+ # action.
154
+ $DAEMON --remove-mqueue "/${NAME}_syslogger"
155
+
156
+ if [ $res -eq 0 ] ; then
157
+ log_end_msg 0
158
+ exit 0
159
+ else
160
+ log_failure_msg "error, failed to stop."
161
+ log_end_msg 1
162
+ exit 1
163
+ fi
164
+ ;;
165
+
166
+ restart|force-reload)
167
+ log_daemon_msg "Restarting $DESC ($NAME)"
168
+ echo
169
+ set +e
170
+
171
+ start-stop-daemon --oknodo --stop --pidfile $PIDFILE --retry=5 --quiet \
172
+ --name $NAME
173
+
174
+ if [ $? -ne 0 ] ; then
175
+ log_failure_msg "error, failed to stop."
176
+ log_end_msg 1
177
+ exit 1
178
+ fi
179
+
180
+ check_homedir
181
+ start
182
+ ;;
183
+
184
+ status)
185
+ if [ ! -r "$PIDFILE" ]; then
186
+ log_warning_msg "$DESC ($NAME) is not running."
187
+ exit 3
188
+ fi
189
+ if read pid < "$PIDFILE" && ps -p "$pid" > /dev/null 2>&1; then
190
+ log_begin_msg "$DESC ($NAME) is running."
191
+ [ $UBUNTU_LOGGING -eq 0 ] && echo
192
+ exit 0
193
+ else
194
+ log_warning_msg "$DESC ($NAME) is not running but PID file '$PIDFILE' exists."
195
+ exit 1
196
+ fi
197
+ ;;
198
+
199
+ *)
200
+ log_failure_msg "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}."
201
+ exit 1
202
+ ;;
203
+ esac
data/debian/postinst ADDED
@@ -0,0 +1,39 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ # summary of how this script can be called:
6
+ # * <postinst> `configure' <most-recently-configured-version>
7
+ # * <old-postinst> `abort-upgrade' <new version>
8
+ # * <conflictor's-postinst> `abort-remove' `in-favour' <package>
9
+ # <new-version>
10
+ # * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
11
+ # <failed-install-package> <version> `removing'
12
+ # <conflicting-package> <version>
13
+ # for details, see http://www.debian.org/doc/debian-policy/ or
14
+ # the debian-policy package
15
+ #
16
+ # quoting from the policy:
17
+ # Any necessary prompting should almost always be confined to the
18
+ # post-installation script, and should be protected with a conditional
19
+ # so that unnecessary prompting doesn't happen if a package's
20
+ # installation fails and the `postinst' is called with `abort-upgrade',
21
+ # `abort-remove' or `abort-deconfigure'.
22
+
23
+ case "$1" in
24
+ configure)
25
+ adduser --quiet --system --group --disabled-password \
26
+ --shell /bin/false --gecos "OverSIP" \
27
+ --home /var/run/oversip oversip || true
28
+ ;;
29
+
30
+ abort-upgrade|abort-remove|abort-deconfigure)
31
+ ;;
32
+
33
+ *)
34
+ echo "postinst called with unknown argument \`$1'" >&2
35
+ exit 1
36
+ ;;
37
+ esac
38
+
39
+ #DEBHELPER#
data/debian/postrm ADDED
@@ -0,0 +1,10 @@
1
+ #!/bin/sh
2
+
3
+ #DEBHELPER#
4
+
5
+ if [ "$1" = "purge" ] ; then
6
+ # remove user/group on purge
7
+ deluser --quiet --remove-home oversip &>/dev/null || true
8
+ fi
9
+
10
+ exit 0
data/debian/rules ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/make -f
2
+ # -*- makefile -*-
3
+
4
+ # Uncomment this to turn on verbose mode.
5
+ #export DH_VERBOSE=1
6
+
7
+ build: build-stamp
8
+
9
+ build-stamp:
10
+ dh_testdir
11
+ touch $@
12
+
13
+ clean:
14
+ dh_testdir
15
+ dh_testroot
16
+ rm -rf build-stamp oversip
17
+ dh_clean
18
+
19
+ install: build
20
+ dh_testdir
21
+ dh_testroot
22
+ dh_clean -k
23
+ dh_installdirs /etc
24
+
25
+ mkdir -p $(CURDIR)/debian/oversip/etc/oversip/
26
+ mkdir -p $(CURDIR)/debian/oversip/etc/oversip/tls/
27
+ mkdir -p $(CURDIR)/debian/oversip/etc/oversip/tls/ca/
28
+ mkdir -p $(CURDIR)/debian/oversip/etc/oversip/tls/utils/
29
+ mkdir -p $(CURDIR)/debian/oversip/usr/share/oversip/
30
+ install -m 644 etc/oversip.conf debian/oversip/etc/oversip/
31
+ install -m 644 etc/proxies.conf debian/oversip/etc/oversip/
32
+ install -m 644 etc/logic.rb debian/oversip/etc/oversip/
33
+ install -m 644 etc/websocket_policy.rb debian/oversip/etc/oversip/
34
+ install -m 755 etc/tls/upgrade-cacert.sh debian/oversip/etc/oversip/tls/
35
+ install -m 644 etc/tls/demo-tls.oversip.net.crt debian/oversip/etc/oversip/tls/
36
+ install -m 600 etc/tls/demo-tls.oversip.net.key debian/oversip/etc/oversip/tls/
37
+ install -m 644 etc/tls/ca/* debian/oversip/etc/oversip/tls/ca/
38
+ install -m 755 etc/tls/utils/* debian/oversip/etc/oversip/tls/utils/
39
+
40
+ # Build architecture-dependent files here.
41
+ binary-arch: install
42
+ # We have nothing to do by default.
43
+
44
+ # Build architecture-independent files here.
45
+ binary-indep: install
46
+ dh_testdir
47
+ dh_testroot
48
+ dh_installchangelogs
49
+ dh_installdocs
50
+ dh_installexamples
51
+ dh_installman
52
+ dh_installinit --restart-after-upgrade -- defaults 20
53
+ dh_link
54
+ dh_strip
55
+ dh_compress
56
+ dh_fixperms
57
+ dh_installcron
58
+ # dh_makeshlibs
59
+ dh_installdeb
60
+ dh_shlibdeps
61
+ dh_gencontrol
62
+ dh_md5sums
63
+ dh_builddeb
64
+
65
+ binary: binary-indep binary-arch
66
+ .PHONY: build clean binary-indep binary-arch binary install
data/etc/logic.rb ADDED
@@ -0,0 +1,181 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ #
4
+ # OverSIP - Simple OverSIP logic example.
5
+ #
6
+ #
7
+
8
+
9
+ class OverSIP::SIP::Logic
10
+
11
+ ### Custom configuration options:
12
+ #
13
+ # Set this to _true_ if the SIP registrar behind OverSIP does not support Path.
14
+ USE_MODULE_REGISTRAR_WITHOUT_PATH = true
15
+ #
16
+ # Set this to _true_ if the SIP proxy/server behind OverSIP performing the authentication
17
+ # is ready to accept a P-Asserted-Identity header from OverSIP indicating the already
18
+ # asserted SIP user of the client's connection (this avoids authenticating all the requests
19
+ # but the first one).
20
+ USE_MODULE_USER_ASSERTION = true
21
+
22
+
23
+ def run
24
+
25
+ log_info "#{@request.sip_method} from #{@request.from.uri} (UA: #{@request.header("User-Agent")}) to #{@request.ruri} via #{@request.transport.upcase} #{@request.source_ip} : #{@request.source_port}"
26
+
27
+ # Check Max-Forwards value (max 10).
28
+ return unless @request.check_max_forwards 10
29
+
30
+ # Assume all the traffic is from clients and help them with NAT issues
31
+ # by forcing rport usage and Outbound mechanism.
32
+ @request.fix_nat
33
+
34
+
35
+ ### In-dialog requests.
36
+
37
+ if @request.in_dialog?
38
+ if @request.loose_route
39
+ log_debug "proxying in-dialog #{@request.sip_method}"
40
+ @request.proxy(:proxy_in_dialog).route
41
+ else
42
+ unless @request.sip_method == :ACK
43
+ log_notice "forbidden in-dialog request without top Route pointing to us => 403"
44
+ @request.reply 403, "forbidden in-dialog request without top Route pointing to us"
45
+ else
46
+ log_notice "ignoring not loose routing ACK"
47
+ end
48
+ end
49
+ return
50
+ end
51
+
52
+
53
+ ### Initial requests.
54
+
55
+ # Check that the request does not contain a top Route pointing to another server.
56
+ if @request.loose_route
57
+ unless @request.sip_method == :ACK
58
+ log_notice "pre-loaded Route not allowed here => 403"
59
+ @request.reply 403, "Pre-loaded Route not allowed"
60
+ else
61
+ log_notice "ignoring ACK initial request"
62
+ end
63
+ return
64
+ end
65
+
66
+
67
+ if USE_MODULE_REGISTRAR_WITHOUT_PATH
68
+ # Extract the Outbound flow token from the RURI.
69
+ OverSIP::SIP::Modules::RegistrarWithoutPath.extract_outbound_from_ruri @request
70
+ end
71
+
72
+
73
+ # The request goes to a client using Outbound through OverSIP.
74
+ if @request.incoming_outbound_requested?
75
+ log_info "routing initial request to an Outbound client"
76
+
77
+ proxy = @request.proxy(:proxy_to_users)
78
+
79
+ proxy.on_success_response do |response|
80
+ log_info "incoming Outbound on_success_response: #{response.status_code} '#{response.reason_phrase}'"
81
+ end
82
+
83
+ proxy.on_failure_response do |response|
84
+ log_info "incoming Outbound on_failure_response: #{response.status_code} '#{response.reason_phrase}'"
85
+ end
86
+
87
+ # on_error() occurs when no SIP response was received fom the peer and, instead, we
88
+ # got some other internal error (timeout, connection error, DNS error....).
89
+ proxy.on_error do |status, reason|
90
+ log_notice "incoming Outbound on_error: #{status} '#{reason}'"
91
+ end
92
+
93
+ # Route the request and return.
94
+ proxy.route
95
+ return
96
+ end
97
+
98
+
99
+ # An initial request with us (OverSIP) as final destination, ok, received, bye...
100
+ if @request.destination_myself?
101
+ log_info "request for myself => 404"
102
+ @request.reply 404, "Ok, I'm here"
103
+ return
104
+ end
105
+
106
+
107
+ # An outgoing initial request.
108
+ case @request.sip_method
109
+
110
+ when :INVITE, :MESSAGE, :OPTIONS, :SUBSCRIBE, :PUBLISH
111
+
112
+ if USE_MODULE_USER_ASSERTION
113
+ ::OverSIP::SIP::Modules::UserAssertion.add_pai @request
114
+ end
115
+
116
+ proxy = @request.proxy(:proxy_out)
117
+
118
+ proxy.on_provisional_response do |response|
119
+ log_info "on_provisional_response: #{response.status_code} '#{response.reason_phrase}'"
120
+ end
121
+
122
+ proxy.on_success_response do |response|
123
+ log_info "on_success_response: #{response.status_code} '#{response.reason_phrase}'"
124
+ end
125
+
126
+ proxy.on_failure_response do |response|
127
+ log_info "on_failure_response: #{response.status_code} '#{response.reason_phrase}'"
128
+ end
129
+
130
+ proxy.on_error do |status, reason|
131
+ log_notice "on_error: #{status} '#{reason}'"
132
+ end
133
+
134
+ proxy.route
135
+ return
136
+
137
+ when :REGISTER
138
+
139
+ if USE_MODULE_REGISTRAR_WITHOUT_PATH
140
+ # Contact mangling for the case in which the registrar does not support Path.
141
+ ::OverSIP::SIP::Modules::RegistrarWithoutPath.add_outbound_to_contact @request
142
+ end
143
+
144
+ proxy = @request.proxy(:proxy_out)
145
+
146
+ proxy.on_success_response do |response|
147
+ if USE_MODULE_REGISTRAR_WITHOUT_PATH
148
+ # Undo changes done to the Contact header provided by the client, so it receives
149
+ # the same value in the 200 response from the registrar.
150
+ ::OverSIP::SIP::Modules::RegistrarWithoutPath.remove_outbound_from_contact response
151
+ end
152
+
153
+ if USE_MODULE_USER_ASSERTION
154
+ # The registrar replies 200 after a REGISTER with credentials so let's assert
155
+ # the current SIP user to this connection.
156
+ ::OverSIP::SIP::Modules::UserAssertion.assert_connection response
157
+ end
158
+ end
159
+
160
+ proxy.on_failure_response do |response|
161
+ if USE_MODULE_USER_ASSERTION
162
+ # We don't add PAI for re-REGISTER, so 401 will be replied, and after it let's
163
+ # revoke the current user assertion (will be re-added upon REGISTER with credentials).
164
+ ::OverSIP::SIP::Modules::UserAssertion.revoke_assertion response
165
+ end
166
+ end
167
+
168
+ proxy.route
169
+ return
170
+
171
+ else
172
+
173
+ log_info "method #{@request.sip_method} not implemented => 501"
174
+ @request.reply 501, "Not Implemented"
175
+ return
176
+
177
+ end
178
+
179
+ end # def run
180
+
181
+ end # class OverSIP::SIP::Logic