sctp-socket 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c30fa4f2df555124cafe30c8440c3429b977d0d6dce57b46fbaee7510c096cb4
4
+ data.tar.gz: 0e008c97688b85e1a2fc27b2af11a5a6262fd755f49aa762e7d6c78fea9ca863
5
+ SHA512:
6
+ metadata.gz: 4f42d5408ad8262084b6df0e6fd199a9dd142fb806f7b603c64a117fd31e2c890ba4090d9c1e04b5491d84e9fb8a77f7d6bc4b39d2da30e982b4fe9d5c17b0a3
7
+ data.tar.gz: 881f42f26d2f080e2962e9ca01ea179b53ebd13bd956d42b44e626613d7f383208f250c7fb621ae9bddcf3bc95de544db63d08767a70a77d68c1c9bf3205ae75
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ *.so
2
+ *.o
3
+ *.log
4
+ *.lock
5
+ Makefile
@@ -0,0 +1,3 @@
1
+ ## 24-Nov-2020
2
+
3
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org' do
2
+ group 'test' do
3
+ gem 'rake'
4
+ gem 'rspec', '~> 3.9'
5
+ end
6
+
7
+ group 'development' do
8
+ gem 'rake-compiler', '~> 1.1'
9
+ end
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,12 @@
1
+ * CHANGES.md
2
+ * certs/djberg96_pub.pem
3
+ * examples/client_example.rb
4
+ * examples/server_example.rb
5
+ * ext/sctp/socket.c
6
+ * ext/sctp/socket.h
7
+ * Gemfile
8
+ * LICENSE
9
+ * Rakefile
10
+ * README.md
11
+ * sctp-socket.gemspec
12
+ * spec/sctp_spec.rb
@@ -0,0 +1,77 @@
1
+ ## Description
2
+
3
+ A Ruby interface for SCTP sockets.
4
+
5
+ WARNING: THIS IS CURRENTLY AN ALPHA PRODUCT. NOT RECOMMENDED FOR PRODUCTION USE AT THIS TIME.
6
+
7
+ ## Prerequisites
8
+
9
+ You will need the sctp development headers installed.
10
+
11
+ On some systems, such as RHEL8, you may need to enable the sctp module.
12
+
13
+ ## Installation
14
+
15
+ `gem install sctp-socket`
16
+
17
+ ## About SCTP
18
+
19
+ The Stream Control Transmission Protocol (SCTP) is a message oriented, reliable
20
+ transport protocol with direct support for multihoming that runs on top of ip,
21
+ and supports both v4 and v6 versions.
22
+
23
+ Like TCP, SCTP provides reliable, connection oriented data delivery with
24
+ congestion control. Unlike TCP, SCTP also provides message boundary preservation,
25
+ ordered and unordered message delivery, multi-streaming and multi-homing.
26
+
27
+ Detection of data corruption, loss of data and duplication of data is achieved
28
+ by using checksums and sequence numbers. A selective retransmission mechanism
29
+ is applied to correct loss or corruption of data.
30
+
31
+ ## Synopsis
32
+
33
+ ```
34
+ # sample_server.rb
35
+ require 'sctp/socket'
36
+
37
+ begin
38
+ port = 62324
39
+ socket = SCTP::Socket.new
40
+ socket.bind(:port => port, :addresses => ['10.0.5.4', '10.0.6.4'])
41
+ socket.set_initmsg(:output_streams => 5, :input_streams => 5, :max_attempts => 4)
42
+ socket.subscribe(:data_io => true)
43
+ socket.listen
44
+
45
+ while true
46
+ data = socket.recvmsgx
47
+ puts data
48
+ end
49
+ ensure
50
+ socket.close
51
+ end
52
+ ```
53
+
54
+ ## Future Plans
55
+
56
+ * Check for notification data and return it if encountered.
57
+ * Add specs.
58
+
59
+ ## Known Issues
60
+
61
+ Please report any issues on the github project page.
62
+
63
+ https://github.com/djberg96/sctp-socket
64
+
65
+ ## License
66
+
67
+ Apache-2.0
68
+
69
+ ## Copyright
70
+
71
+ (C) 2020, Daniel J. Berger
72
+ Al Rights Reserved
73
+
74
+ ## Author
75
+
76
+ Daniel J. Berger
77
+ djberg96 at gmail dot com
@@ -0,0 +1,42 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rbconfig'
4
+ require 'rspec/core/rake_task'
5
+ require 'rake/extensiontask'
6
+ include RbConfig
7
+
8
+ CLEAN.include(
9
+ '**/*.gem', # Gem files
10
+ '**/*.rbc', # Rubinius
11
+ '**/*.o', # C object file
12
+ '**/*.log', # Ruby extension build log
13
+ '**/Makefile', # C Makefile
14
+ '**/conftest.dSYM', # OS X build directory
15
+ "**/*.#{CONFIG['DLEXT']}" # C shared object
16
+ )
17
+
18
+ namespace :gem do
19
+ desc "Create the sys-uname gem"
20
+ task :create => [:clean] do
21
+ require 'rubygems/package'
22
+ spec = eval(IO.read('sctp-socket.gemspec'))
23
+ spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
24
+ Gem::Package.build(spec)
25
+ end
26
+
27
+ desc "Install the sys-uname gem"
28
+ task :install => [:create] do
29
+ file = Dir["*.gem"].first
30
+ sh "gem install -l #{file}"
31
+ end
32
+ end
33
+
34
+ Rake::ExtensionTask.new('socket') do |t|
35
+ t.ext_dir = 'ext/sctp'
36
+ t.lib_dir = 'lib/sctp'
37
+ end
38
+
39
+ RSpec::Core::RakeTask.new
40
+
41
+ task :spec => :compile
42
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
3
+ cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
4
+ MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
5
+ ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
6
+ bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
7
+ A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
8
+ u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
9
+ 75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
10
+ 6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
11
+ iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
12
+ ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
13
+ 74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
14
+ 058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
15
+ HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
16
+ AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
17
+ YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
18
+ /3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
19
+ h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
20
+ 6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
21
+ ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
22
+ 1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
23
+ DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
24
+ ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
25
+ WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
26
+ -----END CERTIFICATE-----
@@ -0,0 +1,11 @@
1
+ require 'socket'
2
+ require 'sctp/socket'
3
+
4
+ begin
5
+ port = 62324
6
+ socket = SCTP::Socket.new
7
+ bytes_sent = socket.sendmsg(:message => "Hello World!", :addresses => ['127.0.0.1'], :port => port, :stream => 2)
8
+ p bytes_sent
9
+ ensure
10
+ socket.close if socket
11
+ end
@@ -0,0 +1,17 @@
1
+ require 'sctp/socket'
2
+
3
+ # Adjust IP addresses as needed
4
+ begin
5
+ port = 62324
6
+ socket = SCTP::Socket.new
7
+ socket.bind(:port => port, :addresses => ['10.0.5.5', '10.0.6.5'])
8
+ socket.set_initmsg(:output_streams => 5, :input_streams => 5, :max_attempts => 4)
9
+ socket.listen
10
+
11
+ while true
12
+ info = socket.recvmsg
13
+ p info
14
+ end
15
+ ensure
16
+ socket.close
17
+ end
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ have_header('netinet/sctp.h')
4
+ have_library('sctp')
5
+ create_makefile('sctp/socket')
@@ -0,0 +1,679 @@
1
+ #include "ruby.h"
2
+ #include <string.h>
3
+ #include <errno.h>
4
+ #include <arpa/inet.h>
5
+ #include <netinet/sctp.h>
6
+
7
+ VALUE mSCTP;
8
+ VALUE cSocket;
9
+ VALUE v_sndrcv_struct;
10
+
11
+ // Helper function to get a hash value via string or symbol.
12
+ VALUE rb_hash_aref2(VALUE v_hash, const char* key){
13
+ VALUE v_key, v_val;
14
+
15
+ v_key = rb_str_new2(key);
16
+ v_val = rb_hash_aref(v_hash, v_key);
17
+
18
+ if(NIL_P(v_val))
19
+ v_val = rb_hash_aref(v_hash, ID2SYM(rb_intern(key)));
20
+
21
+ return v_val;
22
+ }
23
+
24
+ /*
25
+ * Create and return a new SCTP::Socket instance. You may optionally pass in
26
+ * a domain (aka family) value and socket type. By default these are AF_INET
27
+ * and SOCK_SEQPACKET, respectively.
28
+ *
29
+ * Example:
30
+ *
31
+ * socket1 = SCTP::Socket.new
32
+ * socket2 = SCTP::Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
33
+ */
34
+ static VALUE rsctp_init(int argc, VALUE* argv, VALUE self){
35
+ int sock_fd;
36
+ VALUE v_domain, v_type;
37
+
38
+ rb_scan_args(argc, argv, "02", &v_domain, &v_type);
39
+
40
+ if(NIL_P(v_domain))
41
+ v_domain = INT2NUM(AF_INET);
42
+
43
+ if(NIL_P(v_type))
44
+ v_type = INT2NUM(SOCK_SEQPACKET);
45
+
46
+ sock_fd = socket(NUM2INT(v_domain), NUM2INT(v_type), IPPROTO_SCTP);
47
+
48
+ if(sock_fd < 0)
49
+ rb_raise(rb_eSystemCallError, "socket: %s", strerror(errno));
50
+
51
+ rb_iv_set(self, "@domain", v_domain);
52
+ rb_iv_set(self, "@type", v_type);
53
+ rb_iv_set(self, "@sock_fd", INT2NUM(sock_fd));
54
+ rb_iv_set(self, "@association_id", INT2NUM(0));
55
+
56
+ return self;
57
+ }
58
+
59
+ /*
60
+ * Bind a subset of IP addresses associated with the host system on the
61
+ * given port, or a port assigned by the operating system if none is provided.
62
+ *
63
+ * Note that you can both add or remove an address to or from the socket
64
+ * using the SCTP_BINDX_ADD_ADDR (default) or SCTP_BINDX_REM_ADDR constants,
65
+ * respectively.
66
+ *
67
+ * Example:
68
+ *
69
+ * socket = SCTP::Socket.new
70
+ *
71
+ * # Bind 2 addresses
72
+ * socket.bind(:port => 64325, :addresses => ['10.0.4.5', '10.0.5.5'])
73
+ *
74
+ * # Remove 1 later
75
+ * socket.bind(:addresses => ['10.0.4.5'], :flags => SCTP::Socket::BINDX_REM_ADDR)
76
+ *
77
+ * If no addresses are specified, then it will bind to all available interfaces. If
78
+ * no port is specified, then one will be assigned by the host.
79
+ *
80
+ * Returns the port that it was bound to.
81
+ */
82
+ static VALUE rsctp_bind(int argc, VALUE* argv, VALUE self){
83
+ struct sockaddr_in addrs[8];
84
+ int i, sock_fd, num_ip, flags, domain, port;
85
+ VALUE v_addresses, v_port, v_flags, v_address, v_options;
86
+
87
+ rb_scan_args(argc, argv, "01", &v_options);
88
+
89
+ bzero(&addrs, sizeof(addrs));
90
+
91
+ if(NIL_P(v_options))
92
+ v_options = rb_hash_new();
93
+
94
+ v_addresses = rb_hash_aref2(v_options, "addresses");
95
+ v_flags = rb_hash_aref2(v_options, "flags");
96
+ v_port = rb_hash_aref2(v_options, "port");
97
+
98
+ if(NIL_P(v_port))
99
+ port = 0;
100
+ else
101
+ port = NUM2INT(v_port);
102
+
103
+ if(NIL_P(v_flags))
104
+ flags = SCTP_BINDX_ADD_ADDR;
105
+ else
106
+ flags = NUM2INT(v_flags);
107
+
108
+ if(NIL_P(v_addresses))
109
+ num_ip = 1;
110
+ else
111
+ num_ip = RARRAY_LEN(v_addresses);
112
+
113
+ domain = NUM2INT(rb_iv_get(self, "@domain"));
114
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
115
+
116
+ if(num_ip > 1){
117
+ for(i = 0; i < num_ip; i++){
118
+ v_address = RARRAY_PTR(v_addresses)[i];
119
+ addrs[i].sin_family = domain;
120
+ addrs[i].sin_port = htons(port);
121
+ addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
122
+ }
123
+ }
124
+ else{
125
+ addrs[0].sin_family = domain;
126
+ addrs[0].sin_port = htons(port);
127
+ addrs[0].sin_addr.s_addr = htonl(INADDR_ANY);
128
+ }
129
+
130
+ if(sctp_bindx(sock_fd, (struct sockaddr *) addrs, num_ip, flags) != 0)
131
+ rb_raise(rb_eSystemCallError, "sctp_bindx: %s", strerror(errno));
132
+
133
+ if(port == 0){
134
+ struct sockaddr_in sin;
135
+ socklen_t len = sizeof(sin);
136
+
137
+ if(getsockname(sock_fd, (struct sockaddr *)&sin, &len) == -1)
138
+ rb_raise(rb_eSystemCallError, "getsockname: %s", strerror(errno));
139
+
140
+ port = sin.sin_port;
141
+ }
142
+
143
+ return INT2NUM(port);
144
+ }
145
+
146
+ /*
147
+ * Connect the socket to a multihomed peer via the provided array of addresses
148
+ * using the domain specified in the constructor. You must also specify the port.
149
+ *
150
+ * Example:
151
+ *
152
+ * socket = SCTP::Socket.new
153
+ * socket.connect(:port => 62354, :addresses => ['10.0.4.5', '10.0.5.5'])
154
+ *
155
+ * Note that this will also set/update the object's association_id.
156
+ */
157
+ static VALUE rsctp_connect(int argc, VALUE* argv, VALUE self){
158
+ struct sockaddr_in addrs[8];
159
+ int i, num_ip, sock_fd;
160
+ sctp_assoc_t assoc;
161
+ VALUE v_address, v_domain, v_options, v_addresses, v_port;
162
+
163
+ rb_scan_args(argc, argv, "01", &v_options);
164
+
165
+ if(NIL_P(v_options))
166
+ rb_raise(rb_eArgError, "you must specify an array of addresses");
167
+
168
+ Check_Type(v_options, T_HASH);
169
+
170
+ v_addresses = rb_hash_aref2(v_options, "addresses");
171
+ v_port = rb_hash_aref2(v_options, "port");
172
+
173
+ if(NIL_P(v_addresses) || RARRAY_LEN(v_addresses) == 0)
174
+ rb_raise(rb_eArgError, "you must specify an array of addresses containing at least one address");
175
+
176
+ if(NIL_P(v_port))
177
+ rb_raise(rb_eArgError, "you must specify a port");
178
+
179
+ v_domain = rb_iv_get(self, "@domain");
180
+
181
+ num_ip = RARRAY_LEN(v_addresses);
182
+ bzero(&addrs, sizeof(addrs));
183
+
184
+ for(i = 0; i < num_ip; i++){
185
+ v_address = RARRAY_PTR(v_addresses)[i];
186
+ addrs[i].sin_family = NUM2INT(v_domain);
187
+ addrs[i].sin_port = htons(NUM2INT(v_port));
188
+ addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
189
+ }
190
+
191
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
192
+
193
+ if(sctp_connectx(sock_fd, (struct sockaddr *) addrs, num_ip, &assoc) < 0)
194
+ rb_raise(rb_eSystemCallError, "sctp_connectx: %s", strerror(errno));
195
+
196
+ rb_iv_set(self, "@assocation_id", INT2NUM(assoc));
197
+
198
+ return self;
199
+ }
200
+
201
+ /*
202
+ * Close the socket. You should always do this.
203
+ *
204
+ * Example:
205
+ *
206
+ * socket = SCTP::Socket.new
207
+ * socket.close
208
+ */
209
+ static VALUE rsctp_close(VALUE self){
210
+ VALUE v_sock_fd = rb_iv_get(self, "@sock_fd");
211
+
212
+ if(close(NUM2INT(v_sock_fd)))
213
+ rb_raise(rb_eSystemCallError, "close: %s", strerror(errno));
214
+
215
+ return self;
216
+ }
217
+
218
+ static VALUE rsctp_getpeernames(VALUE self){
219
+ VALUE v_assoc_id = rb_iv_get(self, "@assocation_id");
220
+ sctp_assoc_t assoc_id;
221
+ struct sockaddr* addrs;
222
+ int i, sock_fd, num_addrs;
223
+
224
+ bzero(&addrs, sizeof(addrs));
225
+
226
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
227
+ assoc_id = NUM2INT(v_assoc_id);
228
+
229
+ num_addrs = sctp_getpaddrs(sock_fd, assoc_id, &addrs);
230
+
231
+ if(num_addrs < 0){
232
+ sctp_freepaddrs(addrs);
233
+ rb_raise(rb_eSystemCallError, "sctp_getpaddrs: %s", strerror(errno));
234
+ }
235
+
236
+ for(i = 0; i < num_addrs; i++){
237
+ // TODO: Create and return array of IpAddr objects
238
+ }
239
+
240
+ sctp_freepaddrs(addrs);
241
+
242
+ return self;
243
+ }
244
+
245
+ static VALUE rsctp_getlocalnames(VALUE self){
246
+ sctp_assoc_t assoc_id;
247
+ struct sockaddr* addrs;
248
+ int i, sock_fd, num_addrs;
249
+
250
+ bzero(&addrs, sizeof(addrs));
251
+
252
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
253
+ assoc_id = NUM2INT(rb_iv_get(self, "@assocation_id"));
254
+
255
+ num_addrs = sctp_getladdrs(sock_fd, assoc_id, &addrs);
256
+
257
+ if(num_addrs < 0){
258
+ sctp_freeladdrs(addrs);
259
+ rb_raise(rb_eSystemCallError, "sctp_getladdrs: %s", strerror(errno));
260
+ }
261
+
262
+ for(i = 0; i < num_addrs; i++){
263
+ // TODO: Create and return array of IpAddr objects
264
+ }
265
+
266
+ sctp_freeladdrs(addrs);
267
+
268
+ return self;
269
+ }
270
+
271
+ /*
272
+ * Transmit a message to an SCTP endpoint. The following hash of options
273
+ * is permitted:
274
+ *
275
+ * :message -> The message to send to the endpoint. Mandatory.
276
+ * :stream -> The SCTP stream number you wish to send the message on.
277
+ * :to -> An array of addresses to send the message to.
278
+ * :context -> The default context used for the sendmsg call if the send fails.
279
+ * :ppid -> The payload protocol identifier that is passed to the peer endpoint.
280
+ * :flags -> A bitwise integer that contain one or more values that control behavior.
281
+ *
282
+ * Note that the :to option is not mandatory in a one-to-one (SOCK_STREAM)
283
+ * socket connection. However, it must have been set previously via the
284
+ * connect method.
285
+ *
286
+ * Example:
287
+ *
288
+ * socket = SCTP::Socket.new
289
+ *
290
+ * socket.sendmsg(
291
+ * :message => "Hello World!",
292
+ * :stream => 3,
293
+ * :flags => SCTP::Socket::SCTP_UNORDERED | SCTP::Socket::SCTP_SENDALL,
294
+ * :ttl => 100,
295
+ * :to => ['10.0.5.4', '10.0.6.4']
296
+ * )
297
+ */
298
+ static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
299
+ VALUE v_msg, v_ppid, v_flags, v_stream, v_ttl, v_context, v_addresses;
300
+ uint16_t stream;
301
+ uint32_t ppid, flags, ttl, context;
302
+ ssize_t num_bytes;
303
+ struct sockaddr_in addrs[8];
304
+ int sock_fd, size;
305
+
306
+ Check_Type(v_options, T_HASH);
307
+
308
+ bzero(&addrs, sizeof(addrs));
309
+
310
+ v_msg = rb_hash_aref2(v_options, "message");
311
+ v_stream = rb_hash_aref2(v_options, "stream");
312
+ v_ppid = rb_hash_aref2(v_options, "ppid");
313
+ v_context = rb_hash_aref2(v_options, "context");
314
+ v_flags = rb_hash_aref2(v_options, "flags");
315
+ v_ttl = rb_hash_aref2(v_options, "ttl");
316
+ v_addresses = rb_hash_aref2(v_options, "addresses");
317
+
318
+ if(NIL_P(v_stream))
319
+ stream = 0;
320
+ else
321
+ stream = NUM2INT(v_stream);
322
+
323
+ if(NIL_P(v_flags))
324
+ flags = 0;
325
+ else
326
+ flags = NUM2INT(v_stream);
327
+
328
+ if(NIL_P(v_ttl))
329
+ ttl = 0;
330
+ else
331
+ ttl = NUM2INT(v_ttl);
332
+
333
+ if(NIL_P(v_ppid))
334
+ ppid = 0;
335
+ else
336
+ ppid = NUM2INT(v_ppid);
337
+
338
+ if(NIL_P(v_context))
339
+ context = 0;
340
+ else
341
+ context = NUM2INT(v_context);
342
+
343
+ if(!NIL_P(v_addresses)){
344
+ int i, num_ip, port;
345
+ VALUE v_address, v_port;
346
+
347
+ num_ip = RARRAY_LEN(v_addresses);
348
+ v_port = rb_hash_aref2(v_options, "port");
349
+
350
+ if(NIL_P(v_port))
351
+ port = 0;
352
+ else
353
+ port = NUM2INT(v_port);
354
+
355
+ for(i = 0; i < num_ip; i++){
356
+ v_address = RARRAY_PTR(v_addresses)[i];
357
+ addrs[i].sin_family = NUM2INT(rb_iv_get(self, "@domain"));
358
+ addrs[i].sin_port = htons(port);
359
+ addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
360
+ }
361
+
362
+ size = sizeof(addrs);
363
+ }
364
+ else{
365
+ size = 0;
366
+ }
367
+
368
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
369
+
370
+ num_bytes = sctp_sendmsg(
371
+ sock_fd,
372
+ StringValueCStr(v_msg),
373
+ RSTRING_LEN(v_msg),
374
+ (struct sockaddr*)addrs,
375
+ size,
376
+ ppid,
377
+ flags,
378
+ stream,
379
+ ttl,
380
+ context
381
+ );
382
+
383
+ if(num_bytes < 0)
384
+ rb_raise(rb_eSystemCallError, "sctp_sendmsg: %s", strerror(errno));
385
+
386
+ return INT2NUM(num_bytes);
387
+ }
388
+
389
+ /*
390
+ * Receive a message from another SCTP endpoint.
391
+ *
392
+ * Example:
393
+ *
394
+ * begin
395
+ * socket = SCTP::Socket.new
396
+ * socket.bind(:port => 62534, :addresses => ['10.0.4.5', '10.0.5.5'])
397
+ * socket.subscribe(:data_io => 1)
398
+ * socket.listen
399
+ *
400
+ * while true
401
+ * info = socket.recvmsg
402
+ * puts "Received message: #{info.message}"
403
+ * end
404
+ * ensure
405
+ * socket.close
406
+ * end
407
+ */
408
+ static VALUE rsctp_recvmsg(int argc, VALUE* argv, VALUE self){
409
+ VALUE v_flags;
410
+ struct sctp_sndrcvinfo sndrcvinfo;
411
+ struct sockaddr_in clientaddr;
412
+ int flags, bytes, sock_fd;
413
+ char buffer[1024]; // TODO: Let this be configurable?
414
+ socklen_t length;
415
+
416
+ rb_scan_args(argc, argv, "01", &v_flags);
417
+
418
+ if(NIL_P(v_flags))
419
+ flags = 0;
420
+ else
421
+ flags = NUM2INT(v_flags);
422
+
423
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
424
+ length = sizeof(struct sockaddr_in);
425
+ bzero(buffer, sizeof(buffer));
426
+
427
+ bytes = sctp_recvmsg(
428
+ sock_fd,
429
+ buffer,
430
+ sizeof(buffer),
431
+ (struct sockaddr*)&clientaddr,
432
+ &length,
433
+ &sndrcvinfo,
434
+ &flags
435
+ );
436
+
437
+ if(bytes < 0)
438
+ rb_raise(rb_eSystemCallError, "sctp_recvmsg: %s", strerror(errno));
439
+
440
+ // TODO: Check for MSG_NOTIFICATION, return different structs for events.
441
+ /*
442
+ if(flags & MSG_NOTIFICATION){
443
+ union sctp_notification* snp;
444
+ snp = (union sctp_notification*)buffer;
445
+
446
+ switch(snp->sn_type){
447
+ case SCTP_ASSOC_CHANGE:
448
+ break;
449
+ case SCTP_PEER_ADDR_CHANGE:
450
+ break;
451
+ case SCTP_REMOTE_ERROR:
452
+ break;
453
+ case SCTP_SEND_FAILED:
454
+ break;
455
+ case SCTP_SHUTDOWN_EVENT:
456
+ break;
457
+ case SCTP_ADAPTATION_INDICATION:
458
+ break;
459
+ case SCTP_PARTIAL_DELIVERY_EVENT:
460
+ break;
461
+ }
462
+ }
463
+ */
464
+
465
+ return rb_struct_new(v_sndrcv_struct,
466
+ rb_str_new(buffer, bytes),
467
+ UINT2NUM(sndrcvinfo.sinfo_stream),
468
+ UINT2NUM(sndrcvinfo.sinfo_flags),
469
+ UINT2NUM(sndrcvinfo.sinfo_ppid),
470
+ UINT2NUM(sndrcvinfo.sinfo_context),
471
+ UINT2NUM(sndrcvinfo.sinfo_timetolive),
472
+ UINT2NUM(sndrcvinfo.sinfo_assoc_id)
473
+ );
474
+ }
475
+
476
+ /*
477
+ * {
478
+ * :output_streams => 2,
479
+ * :input_streams => 3,
480
+ * :max_attempts => 5,
481
+ * :timeout => 30
482
+ * }
483
+ */
484
+ static VALUE rsctp_set_initmsg(VALUE self, VALUE v_options){
485
+ int sock_fd;
486
+ struct sctp_initmsg initmsg;
487
+ VALUE v_output, v_input, v_attempts, v_timeout;
488
+
489
+ bzero(&initmsg, sizeof(initmsg));
490
+
491
+ v_output = rb_hash_aref2(v_options, "output_streams");
492
+ v_input = rb_hash_aref2(v_options, "input_streams");
493
+ v_attempts = rb_hash_aref2(v_options, "max_attempts");
494
+ v_timeout = rb_hash_aref2(v_options, "timeout");
495
+
496
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
497
+
498
+ if(!NIL_P(v_output))
499
+ initmsg.sinit_num_ostreams = NUM2INT(v_output);
500
+
501
+ if(!NIL_P(v_input))
502
+ initmsg.sinit_max_instreams = NUM2INT(v_input);
503
+
504
+ if(!NIL_P(v_attempts))
505
+ initmsg.sinit_max_attempts = NUM2INT(v_attempts);
506
+
507
+ if(!NIL_P(v_timeout))
508
+ initmsg.sinit_max_init_timeo = NUM2INT(v_timeout);
509
+
510
+ if(setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) < 0)
511
+ rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
512
+
513
+ return self;
514
+ }
515
+
516
+ /*
517
+ * Subscribe to various notification types, which will generate additional
518
+ * data that the socket may receive. The possible notification types are
519
+ * as follows:
520
+ *
521
+ * :association
522
+ * - A change has occurred to an assocation, either a new one has begun or an existing one has end.
523
+ *
524
+ * :address
525
+ * - The state of one of the peer's addresses has experienced a change.
526
+ *
527
+ * :send_failure
528
+ * - The message could not be delivered to a peer.
529
+ *
530
+ * :shutdown
531
+ * - The peer has sent a shutdown to the local endpoint.
532
+ *
533
+ * Others:
534
+ *
535
+ * :adaptation_layer
536
+ * :authentication_event
537
+ * :data_io
538
+ * :peer_error
539
+ * :partial_delivery
540
+ * :sender_dry
541
+ *
542
+ * By default only data_io is subscribed to.
543
+ *
544
+ * Example:
545
+ *
546
+ * socket = SCTP::Socket.new
547
+ *
548
+ * socket.bind(:port => port, :addresses => ['127.0.0.1'])
549
+ * socket.subscribe(:shutdown => true, :send_failure => true)
550
+ */
551
+ static VALUE rsctp_subscribe(VALUE self, VALUE v_options){
552
+ int sock_fd;
553
+ struct sctp_event_subscribe events;
554
+
555
+ bzero(&events, sizeof(events));
556
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
557
+
558
+ if(RTEST(rb_hash_aref2(v_options, "data_io")))
559
+ events.sctp_data_io_event = 1;
560
+
561
+ if(RTEST(rb_hash_aref2(v_options, "association")))
562
+ events.sctp_association_event = 1;
563
+
564
+ if(RTEST(rb_hash_aref2(v_options, "address")))
565
+ events.sctp_address_event = 1;
566
+
567
+ if(RTEST(rb_hash_aref2(v_options, "send_failure")))
568
+ events.sctp_send_failure_event = 1;
569
+
570
+ if(RTEST(rb_hash_aref2(v_options, "peer_error")))
571
+ events.sctp_peer_error_event = 1;
572
+
573
+ if(RTEST(rb_hash_aref2(v_options, "shutdown")))
574
+ events.sctp_shutdown_event = 1;
575
+
576
+ if(RTEST(rb_hash_aref2(v_options, "partial_delivery")))
577
+ events.sctp_partial_delivery_event = 1;
578
+
579
+ if(RTEST(rb_hash_aref2(v_options, "adaptation_layer")))
580
+ events.sctp_adaptation_layer_event = 1;
581
+
582
+ if(RTEST(rb_hash_aref2(v_options, "authentication")))
583
+ events.sctp_authentication_event = 1;
584
+
585
+ if(RTEST(rb_hash_aref2(v_options, "sender_dry")))
586
+ events.sctp_sender_dry_event = 1;
587
+
588
+ if(setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(events)) < 0)
589
+ rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
590
+
591
+ return self;
592
+ }
593
+
594
+ /*
595
+ * Marks the socket referred to by sockfd as a passive socket, i.e. a socket that
596
+ * will be used to accept incoming connection requests.
597
+ *
598
+ * The backlog argument defines the maximum length to which the queue of
599
+ * pending connections for sockfd may grow. The default is 1024.
600
+ *
601
+ * Example:
602
+ *
603
+ * socket = SCTP::Socket.new
604
+ * socket.bind(:port => 62534, :addresses => ['127.0.0.1'])
605
+ * socket.listen
606
+ *
607
+ */
608
+ static VALUE rsctp_listen(int argc, VALUE* argv, VALUE self){
609
+ VALUE v_backlog;
610
+ int backlog, sock_fd;
611
+
612
+ rb_scan_args(argc, argv, "01", &v_backlog);
613
+
614
+ if(NIL_P(v_backlog))
615
+ backlog = 1024;
616
+ else
617
+ backlog = NUM2INT(v_backlog);
618
+
619
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
620
+
621
+ if(listen(sock_fd, backlog) < 0)
622
+ rb_raise(rb_eSystemCallError, "setsockopt: %s", strerror(errno));
623
+
624
+ return self;
625
+ }
626
+
627
+ /*
628
+ * Extracts an association contained by a one-to-many socket connection into
629
+ * a one-to-one style socket. Note that this modifies the underlying sock_fd.
630
+ */
631
+ static VALUE rsctp_peeloff(VALUE self, VALUE v_assoc_id){
632
+ int sock_fd, new_sock_fd;
633
+ sctp_assoc_t assoc_id;
634
+
635
+ sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
636
+ assoc_id = NUM2INT(v_assoc_id);
637
+
638
+ new_sock_fd = sctp_peeloff(sock_fd, assoc_id);
639
+
640
+ if(new_sock_fd < 0)
641
+ rb_raise(rb_eSystemCallError, "sctp_peeloff: %s", strerror(errno));
642
+
643
+ rb_iv_set(self, "@sock_fd", INT2NUM(new_sock_fd));
644
+
645
+ return self;
646
+ }
647
+
648
+ void Init_socket(){
649
+ mSCTP = rb_define_module("SCTP");
650
+ cSocket = rb_define_class_under(mSCTP, "Socket", rb_cObject);
651
+
652
+ v_sndrcv_struct = rb_struct_define(
653
+ "SndRecvInfo", "message", "stream", "flags",
654
+ "ppid", "context", "ttl", "assoc_id", NULL
655
+ );
656
+
657
+ rb_define_method(cSocket, "initialize", rsctp_init, -1);
658
+
659
+ rb_define_method(cSocket, "bind", rsctp_bind, -1);
660
+ rb_define_method(cSocket, "close", rsctp_close, 0);
661
+ rb_define_method(cSocket, "connect", rsctp_connect, -1);
662
+ rb_define_method(cSocket, "getpeernames", rsctp_getpeernames, 0);
663
+ rb_define_method(cSocket, "getlocalnames", rsctp_getlocalnames, 0);
664
+ rb_define_method(cSocket, "listen", rsctp_listen, -1);
665
+ rb_define_method(cSocket, "peeloff!", rsctp_peeloff, 1);
666
+ rb_define_method(cSocket, "recvmsg", rsctp_recvmsg, -1);
667
+ rb_define_method(cSocket, "sendmsg", rsctp_sendmsg, 1);
668
+ rb_define_method(cSocket, "set_initmsg", rsctp_set_initmsg, 1);
669
+ rb_define_method(cSocket, "subscribe", rsctp_subscribe, 1);
670
+
671
+ rb_define_attr(cSocket, "domain", 1, 1);
672
+ rb_define_attr(cSocket, "type", 1, 1);
673
+ rb_define_attr(cSocket, "sock_fd", 1, 1);
674
+ rb_define_attr(cSocket, "association_id", 1, 1);
675
+ rb_define_attr(cSocket, "port", 1, 1);
676
+
677
+ /* 0.0.1: The version of this library */
678
+ rb_define_const(cSocket, "VERSION", rb_str_new2("0.0.1"));
679
+ }
@@ -0,0 +1,18 @@
1
+ #ifndef SCTP_SOCKET_INCLUDED
2
+ #define SCTP_SOCKET_INCLUDED
3
+
4
+ #include <ruby.h>
5
+ #include <netinet/sctp.h>
6
+
7
+ VALUE rb_hash_aref2(VALUE, const char*);
8
+
9
+ void Init_socket();
10
+ void Init_server();
11
+ void Init_client();
12
+
13
+ extern VALUE mSCTP;
14
+ extern VALUE cSocket;
15
+ extern VALUE cClient;
16
+ extern VALUE cServer;
17
+
18
+ #endif
@@ -0,0 +1,7 @@
1
+ #include <sctp/socket.h>
2
+
3
+ VALUE cClient;
4
+
5
+ void Init_client(){
6
+ cClient = rb_define_class_under(cSocket, "Client", rb_cObject);
7
+ }
@@ -0,0 +1,7 @@
1
+ #include <sctp/socket.h>
2
+
3
+ VALUE cServer;
4
+
5
+ void Init_server(){
6
+ cServer = rb_define_class_under(cSocket, "Server", rb_cObject);
7
+ }
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'sctp-socket'
3
+ spec.version = '0.0.1'
4
+ spec.author = 'Daniel Berger'
5
+ spec.email = 'djberg96@gmail.com'
6
+ spec.summary = 'Ruby bindings for SCTP sockets'
7
+ spec.description = 'Ruby bindings for SCTP sockets'
8
+ spec.homepage = 'https://github.com/djberg96/sctp-sockets'
9
+ spec.license = 'Apache-2.0'
10
+ spec.cert_chain = ['certs/djberg96_pub.pem']
11
+
12
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
13
+ f.match(%r{^(test|spec|features)/})
14
+ end
15
+
16
+ spec.extensions = ['ext/sctp/extconf.rb']
17
+
18
+ spec.add_development_dependency 'bundler'
19
+ spec.add_development_dependency 'rake'
20
+ spec.add_development_dependency 'rake-compiler'
21
+ spec.add_development_dependency 'rspec'
22
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sctp-socket
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Berger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
14
+ cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
15
+ MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
16
+ ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
17
+ bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
18
+ A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
19
+ u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
20
+ 75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
21
+ 6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
22
+ iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
23
+ ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
24
+ 74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
25
+ 058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
26
+ HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
27
+ AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
28
+ YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
29
+ /3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
30
+ h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
31
+ 6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
32
+ ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
33
+ 1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
34
+ DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
35
+ ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
36
+ WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
37
+ -----END CERTIFICATE-----
38
+ date: 2020-11-24 00:00:00.000000000 Z
39
+ dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: bundler
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rake
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake-compiler
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ description: Ruby bindings for SCTP sockets
97
+ email: djberg96@gmail.com
98
+ executables: []
99
+ extensions:
100
+ - ext/sctp/extconf.rb
101
+ extra_rdoc_files: []
102
+ files:
103
+ - ".gitignore"
104
+ - CHANGES.md
105
+ - Gemfile
106
+ - LICENSE
107
+ - MANIFEST.md
108
+ - README.md
109
+ - Rakefile
110
+ - certs/djberg96_pub.pem
111
+ - examples/client_example.rb
112
+ - examples/server_example.rb
113
+ - ext/sctp/extconf.rb
114
+ - ext/sctp/socket.c
115
+ - ext/sctp/socket.h
116
+ - ext/sctp/socket/client.c
117
+ - ext/sctp/socket/server.c
118
+ - sctp-socket.gemspec
119
+ homepage: https://github.com/djberg96/sctp-sockets
120
+ licenses:
121
+ - Apache-2.0
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.0.6
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Ruby bindings for SCTP sockets
142
+ test_files: []
Binary file