Module: OverSIP::Utils
- Defined in:
- lib/oversip/utils.rb,
ext/utils/utils_ruby.c
Class Method Summary collapse
-
.compare_ips(string1, string2) ⇒ Object
Returns true if both IP’s are equal (binary comparison).
-
.compare_pure_ips(string1, string2) ⇒ Object
Returns true if both IP’s are equal (binary comparison).
-
.ip?(string) ⇒ Boolean
Ruby functions.
- .ip_type(string) ⇒ Object
-
.normalize_host(*args) ⇒ Object
Returns the normalized printable string of the given IPv4 or IPv6.
-
.normalize_ipv6(*args) ⇒ Object
Returns the normalized printable string of the given IPv6.
-
.parse_haproxy_protocol(string) ⇒ Object
Expects a string like “PROXY TCP4 192.168.0.1 192.168.0.11 56324 443rn” and returns an Array as follows: [ num_bytes, ip_type, ip, port ] where: - num_bytes is the length of the HAProxy Protocol line (to be removed), a Fixnum.
-
.parse_outbound_udp_flow_token(string) ⇒ Object
Expects a string like “1.2.3.4_5060” or “1af:43::ab_9090” and returns an Array as follows: [ ip_type, ip, port ] where: - ip_type is :ipv4 or :ipv6, - ip is a String, - port is a Fixnum If the string is invalid it returns false.
- .pure_ip?(string) ⇒ Boolean
-
.regexp_compare(string, expression) ⇒ Object
This avoid “invalid byte sequence in UTF-8” when the directly doing: string =~ /EXPRESSION/ and string has invalid UTF-8 bytes secuence.
-
.string_compare(string1, string2) ⇒ Object
It ensures that two identical byte secuences are matched regardless they have different encoding.
-
.to_pure_ip(string) ⇒ Object
If the given argument is a IPV6 reference it returns a new string with the pure IPv6.
Class Method Details
.compare_ips(string1, string2) ⇒ Object
Returns true if both IP’s are equal (binary comparison). Returns false if both IP’s are not equal. Returns nil if at least one of the IP’s is not valid IPv4, IPv6 or IPv6 reference. This function also allows comparing an IPv6 with an IPv6 reference.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'ext/utils/utils_ruby.c', line 101
VALUE Utils_compare_ips(VALUE self, VALUE string1, VALUE string2)
{
TRACE();
char *str1, *str2;
long len1, len2;
enum enum_ip_type ip1_type, ip2_type;
if (TYPE(string1) != T_STRING || TYPE(string2) != T_STRING)
rb_raise(rb_eTypeError, "Arguments must be two String");
str1 = RSTRING_PTR(string1);
len1 = RSTRING_LEN(string1);
str2 = RSTRING_PTR(string2);
len2 = RSTRING_LEN(string2);
switch(ip1_type = utils_ip_parser_execute(str1, len1)) {
case(ip_type_error):
return Qnil;
break;
case(ip_type_ipv6_reference):
str1 += 1;
len1 -= 2;
ip1_type = ip_type_ipv6;
break;
default:
break;
}
switch(ip2_type = utils_ip_parser_execute(str2, len2)) {
case(ip_type_error):
return Qnil;
break;
case(ip_type_ipv6_reference):
str2 += 1;
len2 -= 2;
ip2_type = ip_type_ipv6;
break;
default:
break;
}
if (utils_compare_pure_ips(str1, len1, ip1_type, str2, len2, ip2_type))
return Qtrue;
else
return Qfalse;
}
|
.compare_pure_ips(string1, string2) ⇒ Object
Returns true if both IP’s are equal (binary comparison). Returns false if both IP’s are not equal. Returns nil if at least one of the IP’s is not valid IPv4 or IPv6. This function does not allow comparing an IPv6 with an IPv6 reference.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'ext/utils/utils_ruby.c', line 154
VALUE Utils_compare_pure_ips(VALUE self, VALUE string1, VALUE string2)
{
TRACE();
char *str1, *str2;
long len1, len2;
enum enum_ip_type ip1_type, ip2_type;
if (TYPE(string1) != T_STRING || TYPE(string2) != T_STRING)
rb_raise(rb_eTypeError, "Arguments must be two String");
str1 = RSTRING_PTR(string1);
len1 = RSTRING_LEN(string1);
str2 = RSTRING_PTR(string2);
len2 = RSTRING_LEN(string2);
switch(ip1_type = utils_ip_parser_execute(str1, len1)) {
case(ip_type_error):
return Qnil;
break;
case(ip_type_ipv6_reference):
return Qnil;
break;
default:
break;
}
switch(ip2_type = utils_ip_parser_execute(str2, len2)) {
case(ip_type_error):
return Qnil;
break;
case(ip_type_ipv6_reference):
return Qnil;
break;
default:
break;
}
if (utils_compare_pure_ips(str1, len1, ip1_type, str2, len2, ip2_type))
return Qtrue;
else
return Qfalse;
}
|
.ip?(string) ⇒ Boolean
Ruby functions.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'ext/utils/utils_ruby.c', line 21
VALUE Utils_is_ip(VALUE self, VALUE string)
{
TRACE();
char *str;
long len;
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "Argument must be a String");
str = RSTRING_PTR(string);
len = RSTRING_LEN(string);
if (utils_ip_parser_execute(str, len) != ip_type_error)
return Qtrue;
else
return Qfalse;
}
|
.ip_type(string) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'ext/utils/utils_ruby.c', line 66
VALUE Utils_ip_type(VALUE self, VALUE string)
{
TRACE();
char *str;
long len;
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "Argument must be a String");
str = RSTRING_PTR(string);
len = RSTRING_LEN(string);
switch(utils_ip_parser_execute(str, len)) {
case(ip_type_ipv4):
return symbol_ipv4;
break;
case(ip_type_ipv6):
return symbol_ipv6;
break;
case(ip_type_ipv6_reference):
return symbol_ipv6_reference;
break;
default:
return Qfalse;
break;
}
}
|
.normalize_host(*args) ⇒ Object
Returns the normalized printable string of the given IPv4 or IPv6.
-
First argument is a string to normalize. It must be a valid IPv4, IPv6 or IPv6 reference. If not, the method returns the string itself.
-
Second argument is the type of host (:ipv4, :ipv6, :ipv6_reference or :domain).
-
Third argument is optional. If true, returned value is a pure IPv6 even if the first argument is a IPv6 reference.
TODO: Not in use and seems really ugly!
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'ext/utils/utils_ruby.c', line 234
VALUE Utils_normalize_host(int argc, VALUE *argv, VALUE self)
{
TRACE();
VALUE host, ip_type;
int force_pure_ipv6 = 0;
if (argc == 0 || argc > 3)
rb_raise(rb_eTypeError, "Wrong number of arguments (pass one, two or three)");
host = argv[0];
if (TYPE(host) != T_STRING)
rb_raise(rb_eTypeError, "First argument must be a String");
ip_type = argv[1];
if (TYPE(ip_type) != T_SYMBOL)
rb_raise(rb_eTypeError, "Second argument must be a Symbol (:ipv4, :ipv6 or :domain)");
if (argc == 3 && TYPE(argv[2]) != T_NIL && TYPE(argv[2]) != T_FALSE)
force_pure_ipv6 = 1;
if (ip_type == symbol_ipv6 || ip_type == symbol_ipv6_reference)
return utils_normalize_ipv6(host, force_pure_ipv6);
else
return host;
}
|
.normalize_ipv6(*args) ⇒ Object
Returns the normalized printable string of the given IPv6.
-
First argument is a string to normalize. It must be a valid IPv6 or IPv6 reference. If not, the method returns false.
-
Second argument is optional. If true, returned value is a pure IPv6 even if the first argument is a IPv6 reference.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'ext/utils/utils_ruby.c', line 204
VALUE Utils_normalize_ipv6(int argc, VALUE *argv, VALUE self)
{
TRACE();
VALUE string;
int force_pure_ipv6 = 0;
if (argc == 0 || argc > 2)
rb_raise(rb_eTypeError, "Wrong number of arguments (pass one or two)");
string = argv[0];
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "First argument must be a String");
if (argc == 2 && TYPE(argv[1]) != T_NIL && TYPE(argv[1]) != T_FALSE)
force_pure_ipv6 = 1;
return utils_normalize_ipv6(string, force_pure_ipv6);
}
|
.parse_haproxy_protocol(string) ⇒ Object
Expects a string like “PROXY TCP4 192.168.0.1 192.168.0.11 56324 443rn” and returns an Array as follows:
[ num_bytes, ip_type, ip, port ]
where:
- num_bytes is the length of the HAProxy Protocol line (to be removed), a Fixnum.
- ip_type is :ipv4 or :ipv6,
- ip is a String,
- port is a Fixnum
If the string is invalid it returns false.
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'ext/utils/utils_ruby.c', line 338
VALUE Utils_parser_haproxy_protocol(VALUE self, VALUE string)
{
TRACE();
char *str = NULL;
long len = 0;
struct_haproxy_protocol haproxy_protocol;
VALUE num_bytes, ip_type, ip, port;
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "Argument must be a String");
str = RSTRING_PTR(string);
len = RSTRING_LEN(string);
haproxy_protocol = struct_haproxy_protocol_parser_execute(str, len);
if (haproxy_protocol.valid == 0)
return Qfalse;
else {
if (haproxy_protocol.ip_type == haproxy_protocol_ip_type_ipv4)
ip_type = symbol_ipv4;
else
ip_type = symbol_ipv6;
ip = rb_str_new((char *)haproxy_protocol.ip_s, haproxy_protocol.ip_len);
port = INT2FIX(str_to_int((char *)haproxy_protocol.port_s, haproxy_protocol.port_len));
num_bytes = INT2FIX(haproxy_protocol.total_len);
return rb_ary_new3(4, num_bytes, ip_type, ip, port);
}
}
|
.parse_outbound_udp_flow_token(string) ⇒ Object
Expects a string like “1.2.3.4_5060” or “1af:43::ab_9090” and returns an Array as follows:
[ ip_type, ip, port ]
where:
- ip_type is :ipv4 or :ipv6,
- ip is a String,
- port is a Fixnum
If the string is invalid it returns false.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'ext/utils/utils_ruby.c', line 295
VALUE Utils_parser_outbound_udp_flow_token(VALUE self, VALUE string)
{
TRACE();
char *str = NULL;
long len = 0;
struct_outbound_udp_flow_token outbound_udp_flow_token;
VALUE ip_type, ip, port;
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "Argument must be a String");
str = RSTRING_PTR(string);
len = RSTRING_LEN(string);
outbound_udp_flow_token = outbound_udp_flow_token_parser_execute(str, len);
if (outbound_udp_flow_token.valid == 0)
return Qfalse;
else {
if (outbound_udp_flow_token.ip_type == outbound_udp_flow_token_ip_type_ipv4)
ip_type = symbol_ipv4;
else
ip_type = symbol_ipv6;
ip = rb_str_new((char *)outbound_udp_flow_token.ip_s, outbound_udp_flow_token.ip_len);
port = INT2FIX(str_to_int((char *)outbound_udp_flow_token.port_s, outbound_udp_flow_token.port_len));
return rb_ary_new3(3, ip_type, ip, port);
}
}
|
.pure_ip?(string) ⇒ Boolean
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'ext/utils/utils_ruby.c', line 40
VALUE Utils_is_pure_ip(VALUE self, VALUE string)
{
TRACE();
char *str;
long len;
if (TYPE(string) != T_STRING)
rb_raise(rb_eTypeError, "Argument must be a String");
str = RSTRING_PTR(string);
len = RSTRING_LEN(string);
switch(utils_ip_parser_execute(str, len)) {
case(ip_type_ipv4):
return Qtrue;
break;
case(ip_type_ipv6):
return Qtrue;
break;
default:
return Qfalse;
break;
}
}
|
.regexp_compare(string, expression) ⇒ Object
This avoid “invalid byte sequence in UTF-8” when the directly doing:
string =~ /EXPRESSION/
and string has invalid UTF-8 bytes secuence. Also avoids “incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)” NOTE: expression argument must be a String or a Regexp.
18 19 20 21 22 23 24 25 26 |
# File 'lib/oversip/utils.rb', line 18 def self.regexp_compare string, expression string = string.to_s.force_encoding(::Encoding::BINARY) if expression.is_a? ::Regexp expression = /#{expression.source.force_encoding(::Encoding::BINARY)}/ else expression = /#{expression.to_s.force_encoding(::Encoding::BINARY)}/ end string =~ expression end |
.string_compare(string1, string2) ⇒ Object
It ensures that two identical byte secuences are matched regardless they have different encoding. For example in Ruby the following returns false:
"iñaki".force_encoding(::Encoding::BINARY) == "iñaki"
9 10 11 |
# File 'lib/oversip/utils.rb', line 9 def self.string_compare string1, string2 string1.to_s.force_encoding(::Encoding::BINARY) == string2.to_s.force_encoding(::Encoding::BINARY) end |
.to_pure_ip(string) ⇒ Object
If the given argument is a IPV6 reference it returns a new string with the pure IPv6. In any other case, return the given argument.
TODO: Not documented in the API (seems ugly).
267 268 269 270 271 272 273 274 275 276 277 |
# File 'ext/utils/utils_ruby.c', line 267
VALUE Utils_to_pure_ip(VALUE self, VALUE string)
{
TRACE();
char *str;
str = StringValueCStr(string);
if (str[0] == '[')
return rb_str_new(RSTRING_PTR(string)+1, RSTRING_LEN(string)-2);
else
return string;
}
|