summaryrefslogtreecommitdiff
path: root/ruby
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2011-09-21 23:25:11 -0700
committerRuss Allbery <rra@stanford.edu>2011-09-21 23:25:11 -0700
commit4a62a530bb6c151d4e58f3bb0894499ff7b9aadd (patch)
tree9efb5508aebfa5d15b57308482fee3e9e34134ed /ruby
parent717f7d8fbcf7d18c96294943e27d7c012d979758 (diff)
Add Ruby bindings for remctl_set_source_ip
Diffstat (limited to 'ruby')
-rw-r--r--ruby/README4
-rw-r--r--ruby/remctl.c49
-rw-r--r--ruby/test_remctl.rb.in12
3 files changed, 62 insertions, 3 deletions
diff --git a/ruby/README b/ruby/README
index 03b71ba..95f3b78 100644
--- a/ruby/README
+++ b/ruby/README
@@ -99,6 +99,10 @@ FULL INTERFACE
not given, the library default (host/<host> with the realm
determined by the domain-realm mapping) is used.
+ Normally, the source IP used to connect to the server is assigned by
+ the kernel. To use a specific source IP, assign that IP address (as
+ a string) to Remctl.source_ip before calling Remctl.new.
+
Exceptions:
* ArgumentError, TypeError: an invalid argument was supplied
diff --git a/ruby/remctl.c b/ruby/remctl.c
index 4aa85ec..f6a3f6d 100644
--- a/ruby/remctl.c
+++ b/ruby/remctl.c
@@ -6,7 +6,7 @@
*
* Original implementation by Anthony M. Martinez <twopir@nmt.edu>
* Copyright 2010 Anthony M. Martinez <twopir@nmt.edu>
- * Copyright 2010
+ * Copyright 2010, 2011
* The Board of Trustees of the Leland Stanford Junior University
*
* Permission to use, copy, modify, and distribute this software and its
@@ -61,7 +61,8 @@ void Init_remctl(void);
static VALUE cRemctl, cRemctlResult, eRemctlError, eRemctlNotOpen;
/* Since we can't have @ in our names here... */
-static ID AAdefault_port, AAdefault_principal, Ahost, Aport, Aprincipal;
+static ID AAdefault_port, AAdefault_principal, AAsource_ip;
+static ID Ahost, Aport, Aprincipal;
/* Map the remctl_output type constants to strings. */
const struct {
@@ -231,6 +232,36 @@ rb_remctl_default_principal_set(VALUE self UNUSED, VALUE new)
}
+/* call-seq:
+ * Remctl.source_ip -> nil
+ *
+ * Return the default source IP used for a Remctl complex connection. A value
+ * of nil says to let the kernel assign a source IP.
+ */
+static VALUE
+rb_remctl_source_ip_get(VALUE self UNUSED)
+{
+ return rb_cvar_get(cRemctl, AAsource_ip);
+}
+
+
+/* call-seq:
+ * Remctl.source_ip = '127.0.0.1' -> 0
+ *
+ * Change the source IP used for a new instance of a complex connection. A
+ * value of nil indicates the default port.
+ */
+static VALUE
+rb_remctl_source_ip_set(VALUE self UNUSED, VALUE new)
+{
+ if (NIL_P(new))
+ rb_cvar_set(cRemctl, AAsource_ip, Qnil);
+ else
+ rb_cvar_set(cRemctl, AAsource_ip, StringValue(new));
+ return rb_cvar_get(cRemctl, AAsource_ip);
+}
+
+
/*
* Destructor for a Remctl object. Closes the connection and frees the
* underlying memory.
@@ -284,7 +315,7 @@ static VALUE
rb_remctl_reopen(VALUE self)
{
struct remctl *r;
- VALUE vhost, vport, vprinc;
+ VALUE vhost, vport, vprinc, vdefsource;
char *host, *princ;
unsigned int port;
@@ -295,6 +326,12 @@ rb_remctl_reopen(VALUE self)
if (r == NULL)
rb_raise(rb_eNoMemError, "remctl");
+ /* Set the source IP if needed. */
+ vdefsource = rb_cvar_get(cRemctl, AAsource_ip);
+ if (!NIL_P(vdefsource))
+ if (!remctl_set_source_ip(r, StringValuePtr(vdefsource)))
+ rb_raise(eRemctlError, "%s", remctl_error(r));
+
/* Retrieve the stored host, port, and principal values. */
vhost = rb_ivar_get(self, Ahost);
vport = rb_ivar_get(self, Aport);
@@ -439,6 +476,7 @@ Init_remctl(void)
*/
AAdefault_port = rb_intern("@@default_port");
AAdefault_principal = rb_intern("@@default_principal");
+ AAsource_ip = rb_intern("@@source_ip");
Ahost = rb_intern("@host");
Aport = rb_intern("@port");
Aprincipal = rb_intern("@principal");
@@ -446,6 +484,7 @@ Init_remctl(void)
/* Default values for class variables. */
rb_cvar_set(cRemctl, AAdefault_port, UINT2NUM(0));
rb_cvar_set(cRemctl, AAdefault_principal, Qnil);
+ rb_cvar_set(cRemctl, AAsource_ip, Qnil);
/* Getter and setter methods for class variables. */
rb_define_singleton_method(cRemctl, "default_port",
@@ -456,6 +495,10 @@ Init_remctl(void)
rb_remctl_default_principal_get, 0);
rb_define_singleton_method(cRemctl, "default_principal=",
rb_remctl_default_principal_set, 1);
+ rb_define_singleton_method(cRemctl, "source_ip",
+ rb_remctl_source_ip_get, 0);
+ rb_define_singleton_method(cRemctl, "source_ip=",
+ rb_remctl_source_ip_set, 1);
/* Create the Remctl class. */
rb_define_alloc_func(cRemctl, rb_remctl_alloc);
diff --git a/ruby/test_remctl.rb.in b/ruby/test_remctl.rb.in
index ae539b1..df2828b 100644
--- a/ruby/test_remctl.rb.in
+++ b/ruby/test_remctl.rb.in
@@ -185,6 +185,18 @@ class TC_RemctlFull < Test::Unit::TestCase
assert_equal(output[4], 5)
end
+ def test_full_source_ip
+ unless configured? then return end
+ Remctl.source_ip = '127.0.0.1'
+ r = Remctl.new('127.0.0.1', 14373, @principal)
+ r.close
+ Remctl.source_ip = '::1'
+ assert_raise Remctl::Error do
+ Remctl.new('127.0.0.1', 14374, @principal)
+ end
+ Remctl.source_ip = nil
+ end
+
def test_full_errors
unless configured? then return end
assert_raise ArgumentError do Remctl.new end