summaryrefslogtreecommitdiff
path: root/server/main-channel.h
blob: 6e89f14a738c46e6bcd40ef0a054048ff65aeb0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
   Copyright (C) 2009 Red Hat, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __MAIN_CHANNEL_H__
#define __MAIN_CHANNEL_H__

#include <stdint.h>
#include <spice/vd_agent.h>
#include <common/marshaller.h>

#include "red-channel.h"

#define MAIN_CHANNEL(channel) ((MainChannel*)(channel))

// TODO: Defines used to calculate receive buffer size, and also by reds.c
// other options: is to make a reds_main_consts.h, to duplicate defines.
#define REDS_AGENT_WINDOW_SIZE 10
#define REDS_NUM_INTERNAL_AGENT_MESSAGES 1

// approximate max receive message size for main channel
#define MAIN_CHANNEL_RECEIVE_BUF_SIZE \
    (4096 + (REDS_AGENT_WINDOW_SIZE + REDS_NUM_INTERNAL_AGENT_MESSAGES) * SPICE_AGENT_MAX_DATA_SIZE)

struct RedsMigSpice {
    char *host;
    char *cert_subject;
    int port;
    int sport;
};
typedef struct RedsMigSpice RedsMigSpice;

typedef struct MainChannel {
    RedChannel base;
    uint8_t recv_buf[MAIN_CHANNEL_RECEIVE_BUF_SIZE];
    RedsMigSpice mig_target; // TODO: add refs and release (afrer all clients completed migration in one way or the other?)
    int num_clients_mig_wait;
} MainChannel;


MainChannel *main_channel_new(RedsState *reds);
RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t link_id);
/* This is a 'clone' from the reds.h Channel.link callback to allow passing link_id */
MainChannelClient *main_channel_link(MainChannel *, RedClient *client,
     RedsStream *stream, uint32_t link_id, int migration, int num_common_caps,
     uint32_t *common_caps, int num_caps, uint32_t *caps);
void main_channel_close(MainChannel *main_chan); // not destroy, just socket close
void main_channel_push_mouse_mode(MainChannel *main_chan, int current_mode, int is_client_mouse_allowed);
void main_channel_push_agent_connected(MainChannel *main_chan);
void main_channel_push_agent_disconnected(MainChannel *main_chan);
void main_channel_push_multi_media_time(MainChannel *main_chan, int time);
int main_channel_getsockname(MainChannel *main_chan, struct sockaddr *sa, socklen_t *salen);
int main_channel_getpeername(MainChannel *main_chan, struct sockaddr *sa, socklen_t *salen);

int main_channel_is_connected(MainChannel *main_chan);

/* switch host migration */
void main_channel_migrate_switch(MainChannel *main_chan, RedsMigSpice *mig_target);

/* semi seamless migration */

/* returns the number of clients that we are waiting for their connection.
 * try_seamless = 'true' when the seamless-migration=on in qemu command line */
int main_channel_migrate_connect(MainChannel *main_channel, RedsMigSpice *mig_target,
                                 int try_seamless);
void main_channel_migrate_cancel_wait(MainChannel *main_chan);
const RedsMigSpice* main_channel_get_migration_target(MainChannel *main_chan);
/* returns the number of clients for which SPICE_MSG_MAIN_MIGRATE_END was sent*/
int main_channel_migrate_src_complete(MainChannel *main_chan, int success);
void main_channel_on_migrate_connected(MainChannel *main_channel,
                                       gboolean success, gboolean seamless);

#endif