summaryrefslogtreecommitdiffstats
path: root/server/red_tunnel_worker.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/red_tunnel_worker.c')
-rw-r--r--server/red_tunnel_worker.c211
1 files changed, 107 insertions, 104 deletions
diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c
index 79cb8546..6c36fecb 100644
--- a/server/red_tunnel_worker.c
+++ b/server/red_tunnel_worker.c
@@ -537,8 +537,8 @@ typedef struct TunnelPrintService {
} TunnelPrintService;
struct TunnelWorker {
- Channel channel_interface; // for reds
- TunnelChannelClient *channel;
+ RedChannel *channel;
+ TunnelChannelClient *channel_client;
SpiceCoreInterface *core_interface;
SpiceNetWireInstance *sin;
@@ -564,7 +564,7 @@ struct TunnelWorker {
/*********************************************************************
* Tunnel interface
*********************************************************************/
-static void tunnel_channel_disconnect(RedChannel *channel);
+static void tunnel_channel_on_disconnect(RedChannel *channel);
/* networking interface for slirp */
static int qemu_can_output(SlirpUsrNetworkInterface *usr_interface);
@@ -601,23 +601,23 @@ static UserTimer *create_timer(SlirpUsrNetworkInterface *usr_interface,
static void arm_timer(SlirpUsrNetworkInterface *usr_interface, UserTimer *timer, uint32_t ms);
-/* reds interface */
-static void handle_tunnel_channel_link(Channel *channel, RedClient *client,
+/* RedChannel interface */
+
+static void handle_tunnel_channel_link(RedChannel *channel, RedClient *client,
RedsStream *stream, int migration,
int num_common_caps,
uint32_t *common_caps, int num_caps,
uint32_t *caps);
-static void handle_tunnel_channel_shutdown(struct Channel *channel);
-static void handle_tunnel_channel_migrate(struct Channel *channel);
-
+static void handle_tunnel_channel_client_migrate(RedChannelClient *rcc);
+static void red_tunnel_channel_create(TunnelWorker *worker);
static void tunnel_shutdown(TunnelWorker *worker)
{
int i;
red_printf("");
/* shutdown input from channel */
- if (worker->channel) {
- red_channel_shutdown(worker->channel->base.channel);
+ if (worker->channel_client) {
+ red_channel_client_shutdown(&worker->channel_client->base);
}
/* shutdown socket pipe items */
@@ -745,7 +745,7 @@ static void tunnel_socket_free_rcv_buf(RedSocket *sckt, RedSocketRawRcvBuf *rcv_
--sckt->in_data.num_buffers;
__tunnel_worker_free_socket_rcv_buf(sckt->worker, rcv_buf);
++sckt->in_data.num_tokens;
- __process_rcv_buf_tokens(sckt->worker->channel, sckt);
+ __process_rcv_buf_tokens(sckt->worker->channel_client, sckt);
}
static inline void __tunnel_worker_free_socket_rcv_buf(TunnelWorker *worker,
@@ -973,7 +973,7 @@ SPICE_GNUC_VISIBLE void spice_server_net_wire_recv_packet(SpiceNetWireInstance *
TunnelWorker *worker = sin->st->worker;
ASSERT(worker);
- if (worker->channel && worker->channel->base.channel->migrate) {
+ if (worker->channel_client && worker->channel_client->base.channel->migrate) {
return; // during migration and the tunnel state hasn't been restored yet.
}
@@ -1016,15 +1016,9 @@ void *red_tunnel_attach(SpiceCoreInterface *core_interface,
worker->null_interface.worker = worker;
- worker->channel_interface.type = SPICE_CHANNEL_TUNNEL;
- worker->channel_interface.id = 0;
- worker->channel_interface.link = handle_tunnel_channel_link;
- worker->channel_interface.shutdown = handle_tunnel_channel_shutdown;
- worker->channel_interface.migrate = handle_tunnel_channel_migrate;
- worker->channel_interface.data = worker;
+ red_tunnel_channel_create(worker);
- ring_init(&worker->services);
- reds_register_channel(&worker->channel_interface);
+ ring_init(&worker->services);
net_slirp_init(worker->sif->get_ip(worker->sin),
TRUE,
@@ -1096,7 +1090,7 @@ static inline TunnelService *__tunnel_worker_add_service(TunnelWorker *worker, u
#endif
if (!virt_ip) {
new_service->pipe_item.type = PIPE_ITEM_TYPE_SERVICE_IP_MAP;
- red_channel_client_pipe_add(&worker->channel->base, &new_service->pipe_item);
+ red_channel_client_pipe_add(&worker->channel_client->base, &new_service->pipe_item);
}
return new_service;
@@ -1292,24 +1286,24 @@ static RedSocket *tunnel_worker_create_socket(TunnelWorker *worker, uint16_t loc
static void tunnel_worker_free_socket(TunnelWorker *worker, RedSocket *sckt)
{
- if (worker->channel) {
- if (red_channel_client_pipe_item_is_linked(&worker->channel->base,
+ if (worker->channel_client) {
+ if (red_channel_client_pipe_item_is_linked(&worker->channel_client->base,
&sckt->out_data.data_pipe_item)) {
- red_channel_client_pipe_remove_and_release(&worker->channel->base,
+ red_channel_client_pipe_remove_and_release(&worker->channel_client->base,
&sckt->out_data.data_pipe_item);
return;
}
- if (red_channel_client_pipe_item_is_linked(&worker->channel->base,
+ if (red_channel_client_pipe_item_is_linked(&worker->channel_client->base,
&sckt->out_data.status_pipe_item)) {
- red_channel_client_pipe_remove_and_release(&worker->channel->base,
+ red_channel_client_pipe_remove_and_release(&worker->channel_client->base,
&sckt->out_data.status_pipe_item);
return;
}
- if (red_channel_client_pipe_item_is_linked(&worker->channel->base,
+ if (red_channel_client_pipe_item_is_linked(&worker->channel_client->base,
&sckt->out_data.token_pipe_item)) {
- red_channel_client_pipe_remove_and_release(&worker->channel->base,
+ red_channel_client_pipe_remove_and_release(&worker->channel_client->base,
&sckt->out_data.token_pipe_item);
return;
}
@@ -1631,7 +1625,7 @@ static inline int __client_socket_can_receive(RedSocket *sckt)
{
return (((sckt->client_status == CLIENT_SCKT_STATUS_OPEN) ||
(sckt->client_status == CLIENT_SCKT_STATUS_SHUTDOWN_SEND)) &&
- !sckt->worker->channel->mig_inprogress);
+ !sckt->worker->channel_client->mig_inprogress);
}
static int tunnel_channel_handle_socket_token(TunnelChannelClient *channel, RedSocket *sckt,
@@ -1870,7 +1864,7 @@ static void restored_rcv_buf_release(RawTunneledBuffer *buf)
--sckt->in_data.num_buffers;
__tunnel_worker_free_socket_rcv_buf(sckt->worker, (RedSocketRawRcvBuf *)buf);
// for case that ready queue is empty and the client has no tokens
- __process_rcv_buf_tokens(sckt->worker->channel, sckt);
+ __process_rcv_buf_tokens(sckt->worker->channel_client, sckt);
}
RawTunneledBuffer *tunnel_socket_alloc_restored_rcv_buf(RedSocket *sckt)
@@ -1889,7 +1883,7 @@ static void restore_tokens_buf_release(RawTunneledBuffer *buf)
RedSocket *sckt = (RedSocket *)buf->usr_opaque;
sckt->in_data.num_tokens += tokens_buf->num_tokens;
- __process_rcv_buf_tokens(sckt->worker->channel, sckt);
+ __process_rcv_buf_tokens(sckt->worker->channel_client, sckt);
free(tokens_buf);
}
@@ -2182,7 +2176,7 @@ static uint64_t tunnel_channel_handle_migrate_data_get_serial(RedChannelClient *
static uint64_t tunnel_channel_handle_migrate_data(RedChannelClient *base,
uint32_t size, void *msg)
{
- TunnelChannelClient *channel = SPICE_CONTAINEROF(base->channel, TunnelChannelClient, base);
+ TunnelChannelClient *channel = SPICE_CONTAINEROF(base, TunnelChannelClient, base);
TunnelMigrateSocketList *sockets_list;
TunnelMigrateServicesList *services_list;
TunnelMigrateData *migrate_data = msg;
@@ -2790,22 +2784,22 @@ static void tunnel_worker_release_socket_out_data(TunnelWorker *worker, PipeItem
sckt_out_data->push_tail = NULL;
sckt_out_data->push_tail_size = 0;
- if (worker->channel) {
+ if (worker->channel_client) {
// can still send data to socket
if (__client_socket_can_receive(sckt)) {
if (sckt_out_data->ready_chunks_queue.head) {
// the pipe item may already be linked, if for example the send was
// blocked and before it finished and called release, tunnel_socket_send was called
if (!red_channel_client_pipe_item_is_linked(
- &worker->channel->base, &sckt_out_data->data_pipe_item)) {
+ &worker->channel_client->base, &sckt_out_data->data_pipe_item)) {
sckt_out_data->data_pipe_item.type = PIPE_ITEM_TYPE_SOCKET_DATA;
- red_channel_client_pipe_add(&worker->channel->base, &sckt_out_data->data_pipe_item);
+ red_channel_client_pipe_add(&worker->channel_client->base, &sckt_out_data->data_pipe_item);
}
} else if ((sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_SEND) ||
(sckt->slirp_status == SLIRP_SCKT_STATUS_WAIT_CLOSE)) {
- __tunnel_socket_add_fin_to_pipe(worker->channel, sckt);
+ __tunnel_socket_add_fin_to_pipe(worker->channel_client, sckt);
} else if (sckt->slirp_status == SLIRP_SCKT_STATUS_CLOSED) {
- __tunnel_socket_add_close_to_pipe(worker->channel, sckt);
+ __tunnel_socket_add_close_to_pipe(worker->channel_client, sckt);
}
}
}
@@ -2813,7 +2807,7 @@ static void tunnel_worker_release_socket_out_data(TunnelWorker *worker, PipeItem
if (((sckt->slirp_status == SLIRP_SCKT_STATUS_OPEN) ||
(sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_RECV)) &&
- !sckt->in_slirp_send && !worker->channel->mig_inprogress) {
+ !sckt->in_slirp_send && !worker->channel_client->mig_inprogress) {
// for cases that slirp couldn't write whole it data to our socket buffer
net_slirp_socket_can_send_notify(sckt->slirp_sckt);
}
@@ -2935,8 +2929,8 @@ static int tunnel_socket_connect(SlirpUsrNetworkInterface *usr_interface,
red_printf("TUNNEL_DBG");
#endif
worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
- ASSERT(worker->channel);
- ASSERT(!worker->channel->mig_inprogress);
+ ASSERT(worker->channel_client);
+ ASSERT(!worker->channel_client->mig_inprogress);
far_service = tunnel_worker_find_service_by_addr(worker, &dst_addr, (uint32_t)ntohs(dst_port));
@@ -2964,7 +2958,7 @@ static int tunnel_socket_connect(SlirpUsrNetworkInterface *usr_interface,
#endif
*o_usr_s = sckt;
sckt->out_data.status_pipe_item.type = PIPE_ITEM_TYPE_SOCKET_OPEN;
- red_channel_client_pipe_add(&worker->channel->base, &sckt->out_data.status_pipe_item);
+ red_channel_client_pipe_add(&worker->channel_client->base, &sckt->out_data.status_pipe_item);
errno = EINPROGRESS;
return -1;
@@ -2989,7 +2983,7 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
- ASSERT(!worker->channel->mig_inprogress);
+ ASSERT(!worker->channel_client->mig_inprogress);
sckt = (RedSocket *)opaque;
@@ -3014,7 +3008,7 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
}
if (urgent) {
- SET_TUNNEL_ERROR(worker->channel, "urgent msgs not supported");
+ SET_TUNNEL_ERROR(worker->channel_client, "urgent msgs not supported");
tunnel_shutdown(worker);
errno = ECONNRESET;
return -1;
@@ -3037,7 +3031,7 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
red_printf("socket out buffers overflow, socket will be closed"
" (local_port=%d, service_id=%d)",
ntohs(sckt->local_port), sckt->far_service->id);
- tunnel_socket_force_close(worker->channel, sckt);
+ tunnel_socket_force_close(worker->channel_client, sckt);
size_to_send = 0;
} else {
size_to_send = len;
@@ -3050,10 +3044,10 @@ static int tunnel_socket_send(SlirpUsrNetworkInterface *usr_interface, UserSocke
sckt->out_data.data_size += size_to_send;
if (sckt->out_data.ready_chunks_queue.head &&
- !red_channel_client_pipe_item_is_linked(&worker->channel->base,
+ !red_channel_client_pipe_item_is_linked(&worker->channel_client->base,
&sckt->out_data.data_pipe_item)) {
sckt->out_data.data_pipe_item.type = PIPE_ITEM_TYPE_SOCKET_DATA;
- red_channel_client_pipe_add(&worker->channel->base, &sckt->out_data.data_pipe_item);
+ red_channel_client_pipe_add(&worker->channel_client->base, &sckt->out_data.data_pipe_item);
}
}
@@ -3093,7 +3087,7 @@ static int tunnel_socket_recv(SlirpUsrNetworkInterface *usr_interface, UserSocke
ASSERT(opaque);
worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
- ASSERT(!worker->channel->mig_inprogress);
+ ASSERT(!worker->channel_client->mig_inprogress);
sckt = (RedSocket *)opaque;
@@ -3104,14 +3098,14 @@ static int tunnel_socket_recv(SlirpUsrNetworkInterface *usr_interface, UserSocke
if ((sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_RECV) ||
(sckt->slirp_status == SLIRP_SCKT_STATUS_WAIT_CLOSE)) {
- SET_TUNNEL_ERROR(worker->channel, "receive was shutdown");
+ SET_TUNNEL_ERROR(worker->channel_client, "receive was shutdown");
tunnel_shutdown(worker);
errno = ECONNRESET;
return -1;
}
if (sckt->slirp_status == SLIRP_SCKT_STATUS_CLOSED) {
- SET_TUNNEL_ERROR(worker->channel, "slirp socket not connected");
+ SET_TUNNEL_ERROR(worker->channel_client, "slirp socket not connected");
tunnel_shutdown(worker);
errno = ECONNRESET;
return -1;
@@ -3177,7 +3171,7 @@ static void tunnel_socket_shutdown_send(SlirpUsrNetworkInterface *usr_interface,
#ifdef DEBUG_NETWORK
PRINT_SCKT(sckt);
#endif
- ASSERT(!worker->channel->mig_inprogress);
+ ASSERT(!worker->channel_client->mig_inprogress);
if (sckt->slirp_status == SLIRP_SCKT_STATUS_DELAY_ABORT) {
return;
@@ -3189,7 +3183,7 @@ static void tunnel_socket_shutdown_send(SlirpUsrNetworkInterface *usr_interface,
ASSERT(sckt->client_status == CLIENT_SCKT_STATUS_SHUTDOWN_SEND);
sckt->slirp_status = SLIRP_SCKT_STATUS_WAIT_CLOSE;
} else {
- SET_TUNNEL_ERROR(worker->channel, "unexpected tunnel_socket_shutdown_send slirp_status=%d",
+ SET_TUNNEL_ERROR(worker->channel_client, "unexpected tunnel_socket_shutdown_send slirp_status=%d",
sckt->slirp_status);
tunnel_shutdown(worker);
return;
@@ -3200,11 +3194,11 @@ static void tunnel_socket_shutdown_send(SlirpUsrNetworkInterface *usr_interface,
// check if there is still data to send. the fin will be sent after data is released
// channel is alive, otherwise the sockets would have been aborted
if (!sckt->out_data.ready_chunks_queue.head) {
- __tunnel_socket_add_fin_to_pipe(worker->channel, sckt);
+ __tunnel_socket_add_fin_to_pipe(worker->channel_client, sckt);
}
} else { // if client is closed, it means the connection was aborted since we didn't
// received fin from guest
- SET_TUNNEL_ERROR(worker->channel,
+ SET_TUNNEL_ERROR(worker->channel_client,
"unexpected tunnel_socket_shutdown_send client_status=%d",
sckt->client_status);
tunnel_shutdown(worker);
@@ -3229,12 +3223,12 @@ static void tunnel_socket_shutdown_recv(SlirpUsrNetworkInterface *usr_interface,
#ifdef DEBUG_NETWORK
PRINT_SCKT(sckt);
#endif
- ASSERT(!worker->channel->mig_inprogress);
+ ASSERT(!worker->channel_client->mig_inprogress);
/* failure in recv can happen after the client sckt was shutdown
(after client sent FIN, or after slirp sent FIN and client socket was closed */
if (!__should_send_fin_to_guest(sckt)) {
- SET_TUNNEL_ERROR(worker->channel,
+ SET_TUNNEL_ERROR(worker->channel_client,
"unexpected tunnel_socket_shutdown_recv client_status=%d slirp_status=%d",
sckt->client_status, sckt->slirp_status);
tunnel_shutdown(worker);
@@ -3246,7 +3240,7 @@ static void tunnel_socket_shutdown_recv(SlirpUsrNetworkInterface *usr_interface,
} else if (sckt->slirp_status == SLIRP_SCKT_STATUS_SHUTDOWN_SEND) {
sckt->slirp_status = SLIRP_SCKT_STATUS_WAIT_CLOSE;
} else {
- SET_TUNNEL_ERROR(worker->channel,
+ SET_TUNNEL_ERROR(worker->channel_client,
"unexpected tunnel_socket_shutdown_recv slirp_status=%d",
sckt->slirp_status);
tunnel_shutdown(worker);
@@ -3302,11 +3296,11 @@ static void tunnel_socket_close(SlirpUsrNetworkInterface *usr_interface, UserSoc
// check if there is still data to send. the close will be sent after data is released.
// close may already been pushed if it is a forced close
if (!sckt->out_data.ready_chunks_queue.head && !sckt->pushed_close) {
- __tunnel_socket_add_close_to_pipe(worker->channel, sckt);
+ __tunnel_socket_add_close_to_pipe(worker->channel_client, sckt);
}
} else if (sckt->client_status == CLIENT_SCKT_STATUS_CLOSED) {
if (sckt->client_waits_close_ack) {
- __tunnel_socket_add_close_ack_to_pipe(worker->channel, sckt);
+ __tunnel_socket_add_close_ack_to_pipe(worker->channel_client, sckt);
} else {
tunnel_worker_free_socket(worker, sckt);
}
@@ -3333,12 +3327,12 @@ static void arm_timer(SlirpUsrNetworkInterface *usr_interface, UserTimer *timer,
worker = ((RedSlirpNetworkInterface *)usr_interface)->worker;
#ifdef DEBUG_NETWORK
- if (!worker->channel) {
+ if (!worker->channel_client) {
red_printf("channel not connected");
}
#endif
- if (worker->channel && worker->channel->mig_inprogress) {
- SET_TUNNEL_ERROR(worker->channel, "during migration");
+ if (worker->channel_client && worker->channel_client->mig_inprogress) {
+ SET_TUNNEL_ERROR(worker->channel_client, "during migration");
tunnel_shutdown(worker);
return;
}
@@ -3398,27 +3392,25 @@ static void tunnel_worker_disconnect_slirp(TunnelWorker *worker)
/* don't call disconnect from functions that might be called by slirp
since it closes all its sockets and slirp is not aware of it */
-static void tunnel_channel_disconnect(RedChannel *channel)
+static void tunnel_channel_on_disconnect(RedChannel *channel)
{
- TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)channel;
TunnelWorker *worker;
if (!channel) {
return;
}
red_printf("");
- worker = tunnel_channel->worker;
+ worker = (TunnelWorker *)channel->data;
tunnel_worker_disconnect_slirp(worker);
tunnel_worker_clear_routed_network(worker);
- red_channel_destroy(channel);
- worker->channel = NULL;
+ worker->channel_client = NULL;
}
// TODO - not MC friendly, remove
-static void tunnel_channel_disconnect_client(RedChannelClient *rcc)
+static void tunnel_channel_client_on_disconnect(RedChannelClient *rcc)
{
- tunnel_channel_disconnect(rcc->channel);
+ tunnel_channel_on_disconnect(rcc->channel);
}
/* interface for reds */
@@ -3439,7 +3431,7 @@ static void tunnel_channel_hold_pipe_item(RedChannelClient *rcc, PipeItem *item)
{
}
-static void handle_tunnel_channel_link(Channel *channel, RedClient *client,
+static void handle_tunnel_channel_link(RedChannel *channel, RedClient *client,
RedsStream *stream, int migration,
int num_common_caps,
uint32_t *common_caps, int num_caps,
@@ -3447,15 +3439,42 @@ static void handle_tunnel_channel_link(Channel *channel, RedClient *client,
{
TunnelChannelClient *tcc;
TunnelWorker *worker = (TunnelWorker *)channel->data;
- RedChannel *tunnel_channel;
- ChannelCbs channel_cbs = {0,};
- if (worker->channel) {
- tunnel_channel_disconnect(worker->channel->base.channel);
+ if (worker->channel_client) {
+ red_error("tunnel does not support multiple client");
}
+ tcc = (TunnelChannelClient*)red_channel_client_create(sizeof(TunnelChannelClient),
+ channel, client, stream);
+
+ tcc->worker = worker;
+ tcc->worker->channel_client = tcc;
+ net_slirp_set_net_interface(&worker->tunnel_interface.base);
+
+ on_new_tunnel_channel(tcc);
+}
+
+static void handle_tunnel_channel_client_migrate(RedChannelClient *rcc)
+{
+ TunnelChannelClient *tunnel_channel;
+#ifdef DEBUG_NETWORK
+ red_printf("TUNNEL_DBG: MIGRATE STARTED");
+#endif
+ tunnel_channel = (TunnelChannelClient *)rcc;
+ ASSERT(tunnel_channel == tunnel_channel->worker->channel_client);
+ tunnel_channel->mig_inprogress = TRUE;
+ net_slirp_freeze();
+ red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_MIGRATE);
+}
+
+static void red_tunnel_channel_create(TunnelWorker *worker)
+{
+ RedChannel *channel;
+ ChannelCbs channel_cbs;
+ ClientCbs client_cbs = {0,};
+
channel_cbs.config_socket = tunnel_channel_config_socket;
- channel_cbs.disconnect = tunnel_channel_disconnect_client;
+ channel_cbs.on_disconnect = tunnel_channel_client_on_disconnect;
channel_cbs.alloc_recv_buf = tunnel_channel_alloc_msg_rcv_buf;
channel_cbs.release_recv_buf = tunnel_channel_release_msg_rcv_buf;
channel_cbs.hold_item = tunnel_channel_hold_pipe_item;
@@ -3465,39 +3484,23 @@ static void handle_tunnel_channel_link(Channel *channel, RedClient *client,
channel_cbs.handle_migrate_data = tunnel_channel_handle_migrate_data;
channel_cbs.handle_migrate_data_get_serial = tunnel_channel_handle_migrate_data_get_serial;
- tunnel_channel = red_channel_create(sizeof(RedChannel),
- worker->core_interface,
- migration, TRUE,
- tunnel_channel_handle_message,
- &channel_cbs);
-
- if (!tunnel_channel) {
+ channel = red_channel_create(sizeof(RedChannel),
+ worker->core_interface,
+ SPICE_CHANNEL_TUNNEL, 0,
+ FALSE, // TODO: handle migration=TRUE
+ TRUE,
+ tunnel_channel_handle_message,
+ &channel_cbs);
+ if (!channel) {
return;
}
- tcc = (TunnelChannelClient*)red_channel_client_create(
- sizeof(TunnelChannelClient),
- tunnel_channel, client, stream);
- tcc->worker = worker;
- tcc->worker->channel = tcc;
- net_slirp_set_net_interface(&worker->tunnel_interface.base);
-
- on_new_tunnel_channel(tcc);
-}
+ client_cbs.connect = handle_tunnel_channel_link;
+ client_cbs.migrate = handle_tunnel_channel_client_migrate;
+ red_channel_register_client_cbs(channel, &client_cbs);
-static void handle_tunnel_channel_shutdown(struct Channel *channel)
-{
- tunnel_channel_disconnect(((TunnelWorker *)channel->data)->channel->base.channel);
-}
-
-static void handle_tunnel_channel_migrate(struct Channel *channel)
-{
-#ifdef DEBUG_NETWORK
- red_printf("TUNNEL_DBG: MIGRATE STARTED");
-#endif
- TunnelChannelClient *tunnel_channel = ((TunnelWorker *)channel->data)->channel;
- tunnel_channel->mig_inprogress = TRUE;
- net_slirp_freeze();
- red_channel_client_pipe_add_type(&tunnel_channel->base, PIPE_ITEM_TYPE_MIGRATE);
+ worker->channel = channel;
+ red_channel_set_data(channel, worker);
+ reds_register_channel(worker->channel);
}