Skip to content

Commit

Permalink
Separate blocking from non blocking IO
Browse files Browse the repository at this point in the history
  • Loading branch information
Asmod4n committed Mar 16, 2024
1 parent af80934 commit c44b41a
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 186 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ build/

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
build_config.rb.lock
66 changes: 55 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ end
By default libtls looks in /etc/ssl/cert.pem for ca certs, you can find how to change that in the examples below.


Example
=======
Client example with blocking IO
================================
```ruby
client = Tls::Client.new
client.connect('github.com:443').write("GET / HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n")
Expand Down Expand Up @@ -47,7 +47,57 @@ If you later want to change a config setting
client.config.ca_file = '/etc/ssl/cert.pem'
```

You can also create a configuration object to share with several connections.
Client example with non blocking IO
====================================
requires mruby-poll gem
```ruby
tcp_socket = TCPSocket.new "github.com", 443
client = Tls::Client.new
client.connect_socket tcp_socket.fileno, "github.com"
tcp_socket._setnonblock(true)
poll = Poll.new
tcp_socket_pi = poll.add(tcp_socket, Poll::Out)

buf = "GET / HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n"
while buf
unless poll.wait
raise "Can't write to socket"
end
tmp = client.write_nonblock(buf)
case tmp
when :tls_want_pollin
tcp_socket_pi.events = Poll::In
when :tls_want_pollout
tcp_socket_pi.events = Poll::Out
when Fixnum
buf = buf[tmp+1...-1]
end
end

tcp_socket_pi.events = Poll::In
poll.wait
until (buf = client.read_nonblock()).is_a? String
case buf
when :tls_want_pollin
tcp_socket_pi.events = Poll::In
when :tls_want_pollout
tcp_socket_pi.events = Poll::Out
end
unless poll.wait
raise "Can't read from socket"
end
end

puts buf

tcp_socket._setnonblock(false)
client.close
tcp_socket.close
```

Configuration Examples
======================
You can create a configuration object to share with several connections.
```ruby
config = Tls::Config.new # see https://github.com/Asmod4n/mruby-tls/blob/master/mrblib/config.rb for options.

Expand All @@ -60,6 +110,7 @@ client.config = config
```

Server example
==============
```sh
openssl ecparam -name secp256r1 -genkey -out private-key.pem
openssl req -new -x509 -key private-key.pem -out server.pem
Expand All @@ -75,18 +126,11 @@ tls_client.close

Client Connections don't have a configurable config at the moment

The following Errors can be thrown:
```ruby
SystemCallError # Errno::*
Tls::WantPollin # The underlying read file descriptor needs to be readable in order to continue.
Tls::WantPollout # The underlying write file descriptor needs to be writeable in order to continue.
```

This maps the C Api 1:1, to get a overview http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/tls_accept_fds.3?query=tls%5finit&sec=3 is a good starting point.

License
=======
Copyright 2015,2016 Hendrik Beskow
Copyright 2015,2016,2024 Hendrik Beskow

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this project except in compliance with the License.
Expand Down
2 changes: 0 additions & 2 deletions include/mruby/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ MRB_BEGIN_DECL

#define E_TLS_ERROR (mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "Error"))
#define E_TLS_CONFIG_ERROR (mrb_class_get_under(mrb, mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "Config"), "Error"))
#define E_TLS_WANT_POLLIN (mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "WantPollin"))
#define E_TLS_WANT_POLLOUT (mrb_class_get_under(mrb, mrb_module_get(mrb, "Tls"), "WantPollout"))

MRB_END_DECL

Expand Down
2 changes: 1 addition & 1 deletion mrblib/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def self.new(options = {})
instance.noverify(v)
end
else
raise ArgumentError, "unknown option #{k}"
raise ArgumentError, "unknown option #{k.dump}"
end
end
instance
Expand Down
2 changes: 1 addition & 1 deletion mrblib/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def self.new(config = nil)
when NilClass
super()
else
raise ArgumentError, "Cannot handle #{config.class}"
raise ArgumentError, "Cannot handle #{config.class.dump}"
end
end
end
Expand Down
2 changes: 0 additions & 2 deletions mrblib/error.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module Tls
class Error < RuntimeError; end
class WantPollin < Error; end
class WantPollout < Error; end
class Config
class Error < Tls::Error; end
end
Expand Down
Loading

0 comments on commit c44b41a

Please sign in to comment.