Generic socket-level options added
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
diff --git a/doc/sp_getsockopt.3.txt b/doc/sp_getsockopt.3.txt
index 110c9a1..a8323d9 100644
--- a/doc/sp_getsockopt.3.txt
+++ b/doc/sp_getsockopt.3.txt
@@ -15,7 +15,10 @@
DESCRIPTION
-----------
Retrieves the value for the 'option'. The 'level' argument specifies
-the protocol level at which the option resides.
+the protocol level at which the option resides. For generic socket-level options
+use _SP_SOL_SOCKET_ level. For socket-type-specific options use socket type
+for 'level' argument (e.g. _SP_SUB_). For transport-specific options use ID of
+the transport as the 'level' argument (e.g. _SP_TCP_).
The value is stored in the buffer pointed to by 'optval' argument. Size of the
buffer is specified by the 'optvallen' argument. If the size of the option is
@@ -23,6 +26,24 @@
Otherwise, the 'optvallen' will be modified to indicate the actual length of
the option.
+_<sp/sp.h>_ header defines generic socket-level options. The options are as
+follows:
+
+*SP_LINGER*::
+ Option type is int. Default is 1000.
+*SP_SNDBUF*::
+ Option type is int. Default is 128kB.
+*SP_RCVBUF*::
+ Option type is int. Default is 128kB.
+*SP_SNDTIMEO*::
+ Option type is int. Default is 0 (no timeout).
+*SP_RCVTIMEO*::
+ Option type is int. Default is 0 (no timeout).
+*SP_RECONNECT_IVL*::
+ Option type is int. Default is 100.
+*SP_RECONNECT_IVL_MAX*::
+ Option type is int. Default is 0.
+
RETURN VALUE
------------
@@ -37,7 +58,7 @@
*EBADF*::
The provided socket is invalid.
*ENOPROTOOPT*::
-The option is not supported by the protocol.
+The option is unknown at the level indicated.
*ETERM*::
The library is terminating.
diff --git a/doc/sp_setsockopt.3.txt b/doc/sp_setsockopt.3.txt
index e8bca72..10749d2 100644
--- a/doc/sp_setsockopt.3.txt
+++ b/doc/sp_setsockopt.3.txt
@@ -16,11 +16,32 @@
DESCRIPTION
-----------
Sets the value of the 'option'. The 'level' argument specifies the protocol
-level at which the option resides.
+level at which the option resides. For generic socket-level options use
+_SP_SOL_SOCKET_ level. For socket-type-specific options use socket type
+for 'level' argument (e.g. _SP_SUB_). For transport-specific options use ID of
+the transport as the 'level' argument (e.g. _SP_TCP_).
The new value is poited to by 'optval' argument. Size of the option is specified
by the 'optvallen' argument.
+_<sp/sp.h>_ header defines generic socket-level options. The options are as
+follows:
+
+*SP_LINGER*::
+ Option type is int. Default is 1000.
+*SP_SNDBUF*::
+ Option type is int. Default is 128kB.
+*SP_RCVBUF*::
+ Option type is int. Default is 128kB.
+*SP_SNDTIMEO*::
+ Option type is int. Default is 0 (no timeout).
+*SP_RCVTIMEO*::
+ Option type is int. Default is 0 (no timeout).
+*SP_RECONNECT_IVL*::
+ Option type is int. Default is 100.
+*SP_RECONNECT_IVL_MAX*::
+ Option type is int. Default is 0.
+
RETURN VALUE
------------
@@ -35,9 +56,9 @@
*EBADF*::
The provided socket is invalid.
*ENOPROTOOPT*::
-The option is not supported by the protocol.
+The option is unknown at the level indicated.
*EINVAL*::
-The specified value is invalid.
+The specified option value is invalid.
*ETERM*::
The library is terminating.
@@ -47,6 +68,7 @@
----
int linger = 1000;
sp_setsockopt (s, SOL_SP, SP_LINGER, &linger, sizeof (linger));
+sp_setsockopt (s, SP_SUB, SP_SUBSCRIBE, "ABC", 3);
----
diff --git a/src/core/sock.c b/src/core/sock.c
index 7e4e0c2..806bab2 100644
--- a/src/core/sock.c
+++ b/src/core/sock.c
@@ -39,6 +39,14 @@
sp_cp_init (&self->cp);
sp_cond_init (&self->cond);
self->fd = fd;
+
+ /* Default values for SP_SOL_SOCKET options. */
+ self->linger = 1000;
+ self->sndbuf = 128 * 1024;
+ self->rcvbuf = 128 * 1024;
+ self->sndtimeo = 0;
+ self->rcvtimeo = 0;
+ self->reconnect_ivl = 100;
}
void sp_sock_zombify (struct sp_sock *self)
@@ -91,6 +99,7 @@
{
int rc;
struct sp_sockbase *sockbase;
+ int *dst;
sockbase = (struct sp_sockbase*) self;
@@ -104,8 +113,39 @@
/* Generic socket-level options. */
if (level == SP_SOL_SOCKET) {
+ switch (option) {
+ case SP_LINGER:
+ dst = &sockbase->linger;
+ break;
+ case SP_SNDBUF:
+ dst = &sockbase->sndbuf;
+ break;
+ case SP_RCVBUF:
+ dst = &sockbase->rcvbuf;
+ break;
+ case SP_SNDTIMEO:
+ dst = &sockbase->sndtimeo;
+ break;
+ case SP_RCVTIMEO:
+ dst = &sockbase->rcvtimeo;
+ break;
+ case SP_RECONNECT_IVL:
+ dst = &sockbase->reconnect_ivl;
+ break;
+ case SP_RECONNECT_IVL_MAX:
+ dst = &sockbase->reconnect_ivl_max;
+ break;
+ default:
+ sp_cp_unlock (&sockbase->cp);
+ return -ENOPROTOOPT;
+ }
+ if (optvallen != sizeof (int)) {
+ sp_cp_unlock (&sockbase->cp);
+ return -EINVAL;
+ }
+ *dst = *(int*) optval;
sp_cp_unlock (&sockbase->cp);
- return -ENOPROTOOPT;
+ return 0;
}
/* Pattern-specific socket options. */
@@ -130,6 +170,7 @@
{
int rc;
struct sp_sockbase *sockbase;
+ int *src;
sockbase = (struct sp_sockbase*) self;
@@ -143,8 +184,37 @@
/* Generic socket-level options. */
if (level == SP_SOL_SOCKET) {
+ switch (option) {
+ case SP_LINGER:
+ src = &sockbase->linger;
+ break;
+ case SP_SNDBUF:
+ src = &sockbase->sndbuf;
+ break;
+ case SP_RCVBUF:
+ src = &sockbase->rcvbuf;
+ break;
+ case SP_SNDTIMEO:
+ src = &sockbase->sndtimeo;
+ break;
+ case SP_RCVTIMEO:
+ src = &sockbase->rcvtimeo;
+ break;
+ case SP_RECONNECT_IVL:
+ src = &sockbase->reconnect_ivl;
+ break;
+ case SP_RECONNECT_IVL_MAX:
+ src = &sockbase->reconnect_ivl_max;
+ break;
+ default:
+ sp_cp_unlock (&sockbase->cp);
+ return -ENOPROTOOPT;
+ }
+ memcpy (optval, src,
+ *optvallen < sizeof (int) ? *optvallen : sizeof (int));
+ *optvallen = sizeof (int);
sp_cp_unlock (&sockbase->cp);
- return -ENOPROTOOPT;
+ return 0;
}
/* Pattern-specific socket options. */
diff --git a/src/pattern.h b/src/pattern.h
index 1e654c4..777338e 100644
--- a/src/pattern.h
+++ b/src/pattern.h
@@ -81,6 +81,15 @@
/* File descriptor for this socket. */
int fd;
+
+ /* SP_SOL_SOCKET level options. */
+ int linger;
+ int sndbuf;
+ int rcvbuf;
+ int sndtimeo;
+ int rcvtimeo;
+ int reconnect_ivl;
+ int reconnect_ivl_max;
};
/* Initialise the socket. */
diff --git a/src/sp.h b/src/sp.h
index 6ee3d14..8bce28a 100644
--- a/src/sp.h
+++ b/src/sp.h
@@ -150,7 +150,13 @@
#define SP_SOL_SOCKET 0
/* Generic socket options (SP_SOL_SOCKET level). */
-/* TODO */
+#define SP_LINGER 1
+#define SP_SNDBUF 2
+#define SP_RCVBUF 3
+#define SP_SNDTIMEO 4
+#define SP_RCVTIMEO 5
+#define SP_RECONNECT_IVL 6
+#define SP_RECONNECT_IVL_MAX 7
/* Send/recv options. */
#define SP_DONTWAIT 1