Signed-off-by: Cyrill Gorcunov <[email protected]>
---
include/protocols.h | 1 +
net/protocols.c | 19 +++++++++++++++++++
sockets.c | 26 ++++++++++++++++++++++----
syscalls/socket.c | 36 ++++++++++++++++++++++++++++++++++--
4 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/include/protocols.h b/include/protocols.h
index e52d7c3..6414d65 100644
--- a/include/protocols.h
+++ b/include/protocols.h
@@ -4,5 +4,6 @@
extern const char * get_proto_name(unsigned int proto);
extern void find_specific_proto(const char *protoarg);
extern void parse_exclude_protos(const char *arg);
+extern unsigned int find_next_enabled_proto(unsigned int from);
#endif /* _PROTOCOLS_H */
diff --git a/net/protocols.c b/net/protocols.c
index 4c50d0e..0ebeff0 100644
--- a/net/protocols.c
+++ b/net/protocols.c
@@ -103,6 +103,25 @@ void find_specific_proto(const char *protoarg)
exit(EXIT_FAILURE);
}
+unsigned int find_next_enabled_proto(unsigned int from)
+{
+ unsigned int i;
+
+ from %= ARRAY_SIZE(no_protos);
+
+ for (i = from; i < ARRAY_SIZE(no_protos); i++) {
+ if (no_protos[i] == FALSE)
+ return no_protos[i];
+ }
+
+ for (i = 0; i < from; i++) {
+ if (no_protos[i] == FALSE)
+ return no_protos[i];
+ }
+
+ return -1u;
+}
+
void parse_exclude_protos(const char *arg)
{
char *_arg = strdup(arg);
diff --git a/sockets.c b/sockets.c
index fba3aa9..60aeb0c 100644
--- a/sockets.c
+++ b/sockets.c
@@ -133,6 +133,19 @@ static void generate_sockets(void)
lock_cachefile(cachefile, F_WRLCK);
+ /*
+ * Don't loop forever if all protos all are disabled.
+ */
+ if (!do_specific_proto) {
+ for (n = 0; n < (int)ARRAY_SIZE(no_protos); n++) {
+ if (!no_protos[n])
+ break;
+ }
+
+ if (n >= (int)ARRAY_SIZE(no_protos))
+ nr_to_create = 0;
+ }
+
while (nr_to_create > 0) {
struct socket_triplet st;
@@ -150,6 +163,10 @@ static void generate_sockets(void)
if (get_proto_name(st.family) == NULL)
goto skip;
+ BUG_ON(st.family >= ARRAY_SIZE(no_protos));
+ if (no_protos[st.family])
+ goto skip;
+
if (sanitise_socket_triplet(&st) == -1)
rand_proto_type(&st);
@@ -237,16 +254,17 @@ void open_sockets(void)
type = buffer[1];
protocol = buffer[2];
- if (do_specific_proto == TRUE) {
- if (domain != specific_proto) {
- output(1, "ignoring socket cachefile due to
specific protocol request, and stale data in cachefile.\n");
+ if ((do_specific_proto == TRUE && domain != specific_proto) ||
+ (domain < ARRAY_SIZE(no_protos) && no_protos[domain] ==
TRUE)) {
+ output(1, "ignoring socket cachefile due to specific "
+ "protocol request (or protocol disabled), "
+ "and stale data in cachefile.\n");
regenerate:
unlock_cachefile(cachefile); /* drop the
reader lock. */
close(cachefile);
unlink(cachefilename);
generate_sockets();
return;
- }
}
fd = open_socket(domain, type, protocol);
diff --git a/syscalls/socket.c b/syscalls/socket.c
index 21dabb1..3badd86 100644
--- a/syscalls/socket.c
+++ b/syscalls/socket.c
@@ -12,6 +12,7 @@
#include "shm.h"
#include "config.h"
#include "params.h"
+#include "protocols.h"
#include "trinity.h"
struct socket_ptr {
@@ -44,14 +45,30 @@ static const struct socket_ptr socketptrs[] = {
void rand_proto_type(struct socket_triplet *st)
{
+ int n;
+
+ /*
+ * One special moment on packet sockets. They
+ * can be created with SOCK_PACKET, so if
+ * PF_PACKET is disabled, choose some other type.
+ */
+
st->protocol = rand() % PROTO_MAX;
- switch (rand() % 6) {
+ if (st->family == PF_INET && no_protos[PF_PACKET])
+ n = 5;
+ else
+ n = 6;
+
+ switch (rand() % n) {
case 0: st->type = SOCK_DGRAM; break;
case 1: st->type = SOCK_STREAM; break;
case 2: st->type = SOCK_SEQPACKET; break;
case 3: st->type = SOCK_RAW; break;
case 4: st->type = SOCK_RDM; break;
+ /*
+ * Make sure it's last one.
+ */
case 5: st->type = SOCK_PACKET; break;
default: break;
}
@@ -77,9 +94,24 @@ void gen_socket_args(struct socket_triplet *st)
{
if (do_specific_proto == TRUE)
st->family = specific_proto;
- else
+
+ else {
st->family = rand() % TRINITY_PF_MAX;
+ /*
+ * If we get a disabled family, try to find
+ * first next allowed.
+ */
+ BUG_ON(st->family >= ARRAY_SIZE(no_protos));
+ if (no_protos[st->family]) {
+ st->family = find_next_enabled_proto(st->family);
+ if (st->family == -1u) {
+ outputerr("No available socket family found\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
/* sometimes, still gen rand crap */
if ((rand() % 100) == 0) {
rand_proto_type(st);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe trinity" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html