Class: Socket::Option
- Inherits:
-
Object
- Object
- Socket::Option
- Defined in:
- option.c,
option.c
Overview
Socket::Option represents a socket option used by BasicSocket#getsockopt and BasicSocket#setsockopt. A socket option contains the socket #family, protocol #level, option name #optname and option value #data.
Class Method Summary collapse
-
.Socket::Option.bool(family, level, optname, bool) ⇒ Object
Creates a new Socket::Option object which contains boolean as data.
-
.Socket::Option.byte(family, level, optname, integer) ⇒ Object
Creates a new Socket::Option object which contains a byte as data.
-
.Socket::Option.int(family, level, optname, integer) ⇒ Object
Creates a new Socket::Option object which contains an int as data.
-
.Socket::Option.ipv4_multicast_loop(integer) ⇒ Object
Creates a new Socket::Option object for IP_MULTICAST_LOOP.
-
.Socket::Option.ipv4_multicast_ttl(integer) ⇒ Object
Creates a new Socket::Option object for IP_MULTICAST_TTL.
-
.Socket::Option.linger(onoff, secs) ⇒ Object
Creates a new Socket::Option object for SOL_SOCKET/SO_LINGER.
Instance Method Summary collapse
-
#bool ⇒ Boolean
Returns the data in sockopt as an boolean value.
-
#byte ⇒ Integer
Returns the data in sockopt as an byte.
-
#data ⇒ Object
returns the socket option data as a string.
-
#family ⇒ Integer
returns the socket family as an integer.
-
#Socket::Option.new(family, level, optname, data) ⇒ Object
constructor
Returns a new Socket::Option object.
-
#inspect ⇒ String
Returns a string which shows sockopt in human-readable form.
-
#int ⇒ Integer
Returns the data in sockopt as an int.
-
#ipv4_multicast_loop ⇒ Integer
Returns the ipv4_multicast_loop data in sockopt as an integer.
-
#ipv4_multicast_ttl ⇒ Integer
Returns the ipv4_multicast_ttl data in sockopt as an integer.
-
#level ⇒ Integer
returns the socket level as an integer.
-
#linger ⇒ Array
Returns the linger data in sockopt as a pair of boolean and integer.
-
#optname ⇒ Integer
returns the socket option name as an integer.
-
#to_s ⇒ Object
returns the socket option data as a string.
-
#unpack(template) ⇒ Array
Calls String#unpack on sockopt.data.
Constructor Details
#Socket::Option.new(family, level, optname, data) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'option.c', line 92
static VALUE
sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE data)
{
int family = rsock_family_arg(vfamily);
int level = rsock_level_arg(family, vlevel);
int optname = rsock_optname_arg(family, level, voptname);
StringValue(data);
rb_ivar_set(self, rb_intern("family"), INT2NUM(family));
rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
rb_ivar_set(self, rb_intern("optname"), INT2NUM(optname));
rb_ivar_set(self, rb_intern("data"), data);
return self;
}
|
Class Method Details
.Socket::Option.bool(family, level, optname, bool) ⇒ Object
Creates a new Socket::Option object which contains boolean as data. Actually 0 or 1 as int is used.
require 'socket'
p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true)
#=> #<Socket::Option: INET SOCKET KEEPALIVE 1>
p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, false)
#=> #<Socket::Option: AF_INET SOCKET KEEPALIVE 0>
284 285 286 287 288 289 290 291 292 |
# File 'option.c', line 284
static VALUE
sockopt_s_bool(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vbool)
{
int family = rsock_family_arg(vfamily);
int level = rsock_level_arg(family, vlevel);
int optname = rsock_optname_arg(family, level, voptname);
int i = RTEST(vbool) ? 1 : 0;
return rsock_sockopt_new(family, level, optname, pack_var(i));
}
|
.Socket::Option.byte(family, level, optname, integer) ⇒ Object
199 200 201 202 203 204 205 206 |
# File 'option.c', line 199
static VALUE
sockopt_s_byte(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
{
int family = rsock_family_arg(vfamily);
int level = rsock_level_arg(family, vlevel);
int optname = rsock_optname_arg(family, level, voptname);
return rsock_sockopt_new(family, level, optname, sockopt_pack_byte(vint));
}
|
.Socket::Option.int(family, level, optname, integer) ⇒ Object
237 238 239 240 241 242 243 244 |
# File 'option.c', line 237
static VALUE
sockopt_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
{
int family = rsock_family_arg(vfamily);
int level = rsock_level_arg(family, vlevel);
int optname = rsock_optname_arg(family, level, voptname);
return rsock_sockopt_new(family, level, optname, sockopt_pack_int(vint));
}
|
.Socket::Option.ipv4_multicast_loop(integer) ⇒ Object
393 394 395 396 397 398 399 400 401 402 403 |
# File 'option.c', line 393
static VALUE
sockopt_s_ipv4_multicast_loop(VALUE klass, VALUE value)
{
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP)
VALUE o = XCAT(sockopt_pack_,TYPE_IP_MULTICAST_LOOP)(value);
return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_LOOP, o);
#else
# error IPPROTO_IP or IP_MULTICAST_LOOP is not implemented
#endif
}
|
.Socket::Option.ipv4_multicast_ttl(integer) ⇒ Object
445 446 447 448 449 450 451 452 453 454 |
# File 'option.c', line 445
static VALUE
sockopt_s_ipv4_multicast_ttl(VALUE klass, VALUE value)
{
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
VALUE o = XCAT(sockopt_pack_,TYPE_IP_MULTICAST_TTL)(value);
return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_TTL, o);
#else
# error IPPROTO_IP or IP_MULTICAST_TTL is not implemented
#endif
}
|
.Socket::Option.linger(onoff, secs) ⇒ Object
333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'option.c', line 333
static VALUE
sockopt_s_linger(VALUE klass, VALUE vonoff, VALUE vsecs)
{
VALUE tmp;
struct linger l;
memset(&l, 0, sizeof(l));
if (!NIL_P(tmp = rb_check_to_integer(vonoff, "to_int")))
l.l_onoff = NUM2INT(tmp);
else
l.l_onoff = RTEST(vonoff) ? 1 : 0;
l.l_linger = NUM2INT(vsecs);
return rsock_sockopt_new(AF_UNSPEC, SOL_SOCKET, SO_LINGER, pack_var(l));
}
|
Instance Method Details
#bool ⇒ Boolean
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'option.c', line 303
static VALUE
sockopt_bool(VALUE self)
{
int i;
long len;
VALUE data = sockopt_data(self);
StringValue(data);
len = RSTRING_LEN(data);
if (len == 1) {
return *RSTRING_PTR(data) == 0 ? Qfalse : Qtrue;
}
check_size(len, sizeof(int));
memcpy((char*)&i, RSTRING_PTR(data), len);
return i == 0 ? Qfalse : Qtrue;
}
|
#byte ⇒ Integer
217 218 219 220 221 222 223 224 |
# File 'option.c', line 217
static VALUE
sockopt_byte(VALUE self)
{
VALUE data = sockopt_data(self);
StringValue(data);
check_size(RSTRING_LEN(data), sizeof(char));
return CHR2FIX(*RSTRING_PTR(data));
}
|
#data ⇒ String #to_s ⇒ String
182 183 184 185 186 187 188 |
# File 'option.c', line 182
static VALUE
sockopt_data(VALUE self)
{
VALUE v = rb_attr_get(self, rb_intern("data"));
StringValue(v);
return v;
}
|
#family ⇒ Integer
124 125 126 127 128 |
# File 'option.c', line 124
static VALUE
sockopt_family_m(VALUE self)
{
return rb_attr_get(self, rb_intern("family"));
}
|
#inspect ⇒ String
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 |
# File 'option.c', line 1202
static VALUE
sockopt_inspect(VALUE self)
{
int family = NUM2INT(sockopt_family_m(self));
int level = NUM2INT(sockopt_level_m(self));
int optname = NUM2INT(sockopt_optname_m(self));
VALUE data = sockopt_data(self);
VALUE v, ret;
ID family_id, level_id, optname_id;
int inspected;
StringValue(data);
ret = rb_sprintf("#<%s:", rb_obj_classname(self));
family_id = rsock_intern_family_noprefix(family);
if (family_id)
rb_str_catf(ret, " %s", rb_id2name(family_id));
else
rb_str_catf(ret, " family:%d", family);
if (level == SOL_SOCKET) {
rb_str_cat2(ret, " SOCKET");
optname_id = rsock_intern_so_optname(optname);
if (optname_id)
rb_str_catf(ret, " %s", rb_id2name(optname_id));
else
rb_str_catf(ret, " optname:%d", optname);
}
#ifdef HAVE_SYS_UN_H
else if (family == AF_UNIX) {
rb_str_catf(ret, " level:%d", level);
optname_id = rsock_intern_local_optname(optname);
if (optname_id)
rb_str_catf(ret, " %s", rb_id2name(optname_id));
else
rb_str_catf(ret, " optname:%d", optname);
}
#endif
else if (IS_IP_FAMILY(family)) {
level_id = rsock_intern_iplevel(level);
if (level_id)
rb_str_catf(ret, " %s", rb_id2name(level_id));
else
rb_str_catf(ret, " level:%d", level);
v = optname_to_sym(level, optname);
if (SYMBOL_P(v))
rb_str_catf(ret, " %"PRIsVALUE, rb_sym2str(v));
else
rb_str_catf(ret, " optname:%d", optname);
}
else {
rb_str_catf(ret, " level:%d", level);
rb_str_catf(ret, " optname:%d", optname);
}
inspected = 0;
if (level == SOL_SOCKET)
family = AF_UNSPEC;
switch (family) {
case AF_UNSPEC:
switch (level) {
case SOL_SOCKET:
switch (optname) {
# if defined(SO_DEBUG) /* POSIX */
case SO_DEBUG: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_ERROR) /* POSIX */
case SO_ERROR: inspected = inspect_errno(level, optname, data, ret); break;
# endif
# if defined(SO_TYPE) /* POSIX */
case SO_TYPE: inspected = inspect_socktype(level, optname, data, ret); break;
# endif
# if defined(SO_ACCEPTCONN) /* POSIX */
case SO_ACCEPTCONN: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_BROADCAST) /* POSIX */
case SO_BROADCAST: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_REUSEADDR) /* POSIX */
case SO_REUSEADDR: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_KEEPALIVE) /* POSIX */
case SO_KEEPALIVE: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_OOBINLINE) /* POSIX */
case SO_OOBINLINE: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_SNDBUF) /* POSIX */
case SO_SNDBUF: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_RCVBUF) /* POSIX */
case SO_RCVBUF: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_DONTROUTE) /* POSIX */
case SO_DONTROUTE: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_RCVLOWAT) /* POSIX */
case SO_RCVLOWAT: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_SNDLOWAT) /* POSIX */
case SO_SNDLOWAT: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(SO_LINGER) /* POSIX */
case SO_LINGER: inspected = inspect_linger(level, optname, data, ret); break;
# endif
# if defined(SO_RCVTIMEO) /* POSIX */
case SO_RCVTIMEO: inspected = inspect_timeval_as_interval(level, optname, data, ret); break;
# endif
# if defined(SO_SNDTIMEO) /* POSIX */
case SO_SNDTIMEO: inspected = inspect_timeval_as_interval(level, optname, data, ret); break;
# endif
# if defined(SO_PEERCRED) /* GNU/Linux, OpenBSD */
case SO_PEERCRED: inspected = inspect_peercred(level, optname, data, ret); break;
# endif
}
break;
}
break;
case AF_INET:
#ifdef INET6
case AF_INET6:
#endif
switch (level) {
# if defined(IPPROTO_IP)
case IPPROTO_IP:
switch (optname) {
# if defined(IP_MULTICAST_IF) && defined(HAVE_TYPE_STRUCT_IP_MREQN) /* 4.4BSD, GNU/Linux */
case IP_MULTICAST_IF: inspected = inspect_ipv4_multicast_if(level, optname, data, ret); break;
# endif
# if defined(IP_ADD_MEMBERSHIP) /* 4.4BSD, GNU/Linux */
case IP_ADD_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break;
# endif
# if defined(IP_DROP_MEMBERSHIP) /* 4.4BSD, GNU/Linux */
case IP_DROP_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break;
# endif
# if defined(IP_MULTICAST_LOOP) /* 4.4BSD, GNU/Linux */
case IP_MULTICAST_LOOP: inspected = inspect_ipv4_multicast_loop(level, optname, data, ret); break;
# endif
# if defined(IP_MULTICAST_TTL) /* 4.4BSD, GNU/Linux */
case IP_MULTICAST_TTL: inspected = inspect_ipv4_multicast_ttl(level, optname, data, ret); break;
# endif
}
break;
# endif
# if defined(IPPROTO_IPV6)
case IPPROTO_IPV6:
switch (optname) {
# if defined(IPV6_MULTICAST_HOPS) /* POSIX */
case IPV6_MULTICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(IPV6_MULTICAST_IF) /* POSIX */
case IPV6_MULTICAST_IF: inspected = inspect_ipv6_multicast_if(level, optname, data, ret); break;
# endif
# if defined(IPV6_MULTICAST_LOOP) /* POSIX */
case IPV6_MULTICAST_LOOP: inspected = inspect_uint(level, optname, data, ret); break;
# endif
# if defined(IPV6_JOIN_GROUP) /* POSIX */
case IPV6_JOIN_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
# endif
# if defined(IPV6_LEAVE_GROUP) /* POSIX */
case IPV6_LEAVE_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
# endif
# if defined(IPV6_UNICAST_HOPS) /* POSIX */
case IPV6_UNICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(IPV6_V6ONLY) /* POSIX */
case IPV6_V6ONLY: inspected = inspect_int(level, optname, data, ret); break;
# endif
}
break;
# endif
# if defined(IPPROTO_TCP)
case IPPROTO_TCP:
switch (optname) {
# if defined(TCP_NODELAY) /* POSIX */
case TCP_NODELAY: inspected = inspect_int(level, optname, data, ret); break;
# endif
# if defined(TCP_INFO) && defined(HAVE_TYPE_STRUCT_TCP_INFO) /* Linux, FreeBSD */
case TCP_INFO: inspected = inspect_tcp_info(level, optname, data, ret); break;
# endif
}
break;
# endif
}
break;
#ifdef HAVE_SYS_UN_H
case AF_UNIX:
switch (level) {
case 0:
switch (optname) {
# if defined(LOCAL_PEERCRED)
case LOCAL_PEERCRED: inspected = inspect_local_peercred(level, optname, data, ret); break;
# endif
}
break;
}
break;
#endif
}
if (!inspected) {
rb_str_cat2(ret, " ");
rb_str_append(ret, rb_str_dump(data));
}
rb_str_cat2(ret, ">");
return ret;
}
|
#int ⇒ Integer
257 258 259 260 261 262 263 264 265 266 |
# File 'option.c', line 257
static VALUE
sockopt_int(VALUE self)
{
int i;
VALUE data = sockopt_data(self);
StringValue(data);
check_size(RSTRING_LEN(data), sizeof(int));
memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
return INT2NUM(i);
}
|
#ipv4_multicast_loop ⇒ Integer
Returns the ipv4_multicast_loop data in sockopt as an integer.
sockopt = Socket::Option.ipv4_multicast_loop(10)
p sockopt.ipv4_multicast_loop => 10
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'option.c', line 414
static VALUE
sockopt_ipv4_multicast_loop(VALUE self)
{
int family = NUM2INT(sockopt_family_m(self));
int level = sockopt_level(self);
int optname = sockopt_optname(self);
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP)
if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_LOOP) {
return XCAT(sockopt_,TYPE_IP_MULTICAST_LOOP)(self);
}
#endif
rb_raise(rb_eTypeError, "ipv4_multicast_loop socket option expected");
UNREACHABLE_RETURN(Qnil);
}
|
#ipv4_multicast_ttl ⇒ Integer
Returns the ipv4_multicast_ttl data in sockopt as an integer.
sockopt = Socket::Option.ipv4_multicast_ttl(10)
p sockopt.ipv4_multicast_ttl => 10
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
# File 'option.c', line 465
static VALUE
sockopt_ipv4_multicast_ttl(VALUE self)
{
int family = NUM2INT(sockopt_family_m(self));
int level = sockopt_level(self);
int optname = sockopt_optname(self);
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_TTL) {
return XCAT(sockopt_,TYPE_IP_MULTICAST_TTL)(self);
}
#endif
rb_raise(rb_eTypeError, "ipv4_multicast_ttl socket option expected");
UNREACHABLE_RETURN(Qnil);
}
|
#level ⇒ Integer
145 146 147 148 149 |
# File 'option.c', line 145
static VALUE
sockopt_level_m(VALUE self)
{
return INT2NUM(sockopt_level(self));
}
|
#linger ⇒ Array
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'option.c', line 356
static VALUE
sockopt_linger(VALUE self)
{
int level = sockopt_level(self);
int optname = sockopt_optname(self);
VALUE data = sockopt_data(self);
struct linger l;
VALUE vonoff, vsecs;
if (level != SOL_SOCKET || optname != SO_LINGER)
rb_raise(rb_eTypeError, "linger socket option expected");
check_size(RSTRING_LEN(data), sizeof(struct linger));
memcpy((char*)&l, RSTRING_PTR(data), sizeof(struct linger));
switch (l.l_onoff) {
case 0: vonoff = Qfalse; break;
case 1: vonoff = Qtrue; break;
default: vonoff = INT2NUM(l.l_onoff); break;
}
vsecs = INT2NUM(l.l_linger);
return rb_assoc_new(vonoff, vsecs);
}
|
#optname ⇒ Integer
166 167 168 169 170 |
# File 'option.c', line 166
static VALUE
sockopt_optname_m(VALUE self)
{
return INT2NUM(sockopt_optname(self));
}
|
#data ⇒ String #to_s ⇒ String
182 183 184 185 186 187 188 |
# File 'option.c', line 182
static VALUE
sockopt_data(VALUE self)
{
VALUE v = rb_attr_get(self, rb_intern("data"));
StringValue(v);
return v;
}
|
#unpack(template) ⇒ Array
1431 1432 1433 1434 1435 |
# File 'option.c', line 1431
static VALUE
sockopt_unpack(VALUE self, VALUE template)
{
return rb_funcall(sockopt_data(self), rb_intern("unpack"), 1, template);
}
|