REORG/MEDIUM: stream_interface: initialize socket ops from descriptors
diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h
index ec8d5d0..2123696 100644
--- a/include/proto/stream_interface.h
+++ b/include/proto/stream_interface.h
@@ -41,6 +41,9 @@
 void stream_int_chk_rcv(struct stream_interface *si);
 void stream_int_chk_snd(struct stream_interface *si);
 
+extern struct sock_ops stream_int_embedded;
+extern struct sock_ops stream_int_task;
+
 struct task *stream_int_register_handler(struct stream_interface *si,
 					 struct si_applet *app);
 struct task *stream_int_register_handler_task(struct stream_interface *si,
@@ -95,6 +98,11 @@
 	return t->ptr.s;
 }
 
+static inline void stream_interface_prepare(struct stream_interface *si, const struct sock_ops *ops)
+{
+	memcpy(&si->sock, ops, sizeof(si->sock));
+}
+
 #endif /* _PROTO_STREAM_INTERFACE_H */
 
 /*
diff --git a/include/proto/stream_sock.h b/include/proto/stream_sock.h
index 9e1bc3f..f66d321 100644
--- a/include/proto/stream_sock.h
+++ b/include/proto/stream_sock.h
@@ -39,8 +39,8 @@
 void stream_sock_shutw(struct stream_interface *si);
 void stream_sock_chk_rcv(struct stream_interface *si);
 void stream_sock_chk_snd(struct stream_interface *si);
-void stream_sock_prepare_interface(struct stream_interface *si);
 
+extern struct sock_ops stream_sock;
 
 /* This either returns the sockname or the original destination address. Code
  * inspired from Patrick Schaaf's example of nf_getsockname() implementation.
diff --git a/src/backend.c b/src/backend.c
index 5bec608..f125931 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -973,7 +973,7 @@
 	 * decide here if we can reuse the connection by comparing the
 	 * session's freshly assigned target with the stream interface's.
 	 */
-	stream_sock_prepare_interface(s->req->cons);
+	stream_interface_prepare(s->req->cons, &stream_sock);
 	s->req->cons->connect = tcp_connect_server;
 	s->req->cons->get_src = getsockname;
 	s->req->cons->get_dst = getpeername;
diff --git a/src/peers.c b/src/peers.c
index 8c8795a..31fb8d9 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1182,7 +1182,7 @@
 	if (s->be->options2 & PR_O2_INDEPSTR)
 		s->si[1].flags |= SI_FL_INDEP_STR;
 
-	stream_sock_prepare_interface(&s->si[1]);
+	stream_interface_prepare(&s->si[1], &stream_sock);
 	s->si[1].release = NULL;
 
 	session_init_srv_conn(s);
diff --git a/src/session.c b/src/session.c
index 96b93b9..5cddabd 100644
--- a/src/session.c
+++ b/src/session.c
@@ -184,7 +184,7 @@
 		s->si[0].flags = SI_FL_CAP_SPLTCP; /* TCP/TCPv6 splicing possible */
 
 	/* add the various callbacks */
-	stream_sock_prepare_interface(&s->si[0]);
+	stream_interface_prepare(&s->si[0], &stream_sock);
 
 	/* pre-initialize the other side's stream interface to an INIT state. The
 	 * callbacks will be initialized before attempting to connect.
diff --git a/src/stream_interface.c b/src/stream_interface.c
index b6188d0..35ebc30 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -32,6 +32,28 @@
 #include <proto/stream_sock.h>
 #include <proto/task.h>
 
+/* socket operations for embedded tasks */
+struct sock_ops stream_int_embedded = {
+	.update  = stream_int_update_embedded,
+	.shutr   = stream_int_shutr,
+	.shutw   = stream_int_shutw,
+	.chk_rcv = stream_int_chk_rcv,
+	.chk_snd = stream_int_chk_snd,
+	.read    = NULL,
+	.write   = NULL,
+};
+
+/* socket operations for external tasks */
+struct sock_ops stream_int_task = {
+	.update  = stream_int_update,
+	.shutr   = stream_int_shutr,
+	.shutw   = stream_int_shutw,
+	.chk_rcv = stream_int_chk_rcv,
+	.chk_snd = stream_int_chk_snd,
+	.read    = NULL,
+	.write   = NULL,
+};
+
 /*
  * This function only has to be called once after a wakeup event in case of
  * suspected timeout. It controls the stream interface timeouts and sets
@@ -308,13 +330,7 @@
 {
 	DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si->owner);
 
-	si->sock.update  = stream_int_update_embedded;
-	si->sock.shutr   = stream_int_shutr;
-	si->sock.shutw   = stream_int_shutw;
-	si->sock.chk_rcv = stream_int_chk_rcv;
-	si->sock.chk_snd = stream_int_chk_snd;
-	si->sock.read    = NULL;
-	si->sock.write   = NULL;
+	stream_interface_prepare(si, &stream_int_embedded);
 	si->connect = NULL;
 	set_target_applet(&si->target, app);
 	si->applet.state = 0;
@@ -337,13 +353,7 @@
 
 	DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", fct, si, si->owner);
 
-	si->sock.update  = stream_int_update;
-	si->sock.shutr   = stream_int_shutr;
-	si->sock.shutw   = stream_int_shutw;
-	si->sock.chk_rcv = stream_int_chk_rcv;
-	si->sock.chk_snd = stream_int_chk_snd;
-	si->sock.read    = NULL;
-	si->sock.write   = NULL;
+	stream_interface_prepare(si, &stream_int_task);
 	si->connect = NULL;
 	clear_target(&si->target);
 	si->release   = NULL;
diff --git a/src/stream_sock.c b/src/stream_sock.c
index a77ad39..93e0a92 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -1296,19 +1296,16 @@
 	return 0;
 }
 
-
-/* Prepare a stream interface to be used in socket mode. */
-void stream_sock_prepare_interface(struct stream_interface *si)
-{
-	si->sock.update  = stream_sock_data_finish;
-	si->sock.shutr   = stream_sock_shutr;
-	si->sock.shutw   = stream_sock_shutw;
-	si->sock.chk_rcv = stream_sock_chk_rcv;
-	si->sock.chk_snd = stream_sock_chk_snd;
-	si->sock.read    = stream_sock_read;
-	si->sock.write   = stream_sock_write;
-}
-
+/* stream sock operations */
+struct sock_ops stream_sock = {
+	.update  = stream_sock_data_finish,
+	.shutr   = stream_sock_shutr,
+	.shutw   = stream_sock_shutw,
+	.chk_rcv = stream_sock_chk_rcv,
+	.chk_snd = stream_sock_chk_snd,
+	.read    = stream_sock_read,
+	.write   = stream_sock_write,
+};
 
 /*
  * Local variables: