1 /*
2 * Copyright 2021 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "proxy_client.h"
7
8 #include <unistd.h>
9
10 #include "server/render_protocol.h"
11
12 #include "proxy_server.h"
13
14 bool
proxy_client_destroy_context(struct proxy_client * client,uint32_t ctx_id)15 proxy_client_destroy_context(struct proxy_client *client, uint32_t ctx_id)
16 {
17 const struct render_client_op_destroy_context_request req = {
18 .header.op = RENDER_CLIENT_OP_DESTROY_CONTEXT,
19 .ctx_id = ctx_id,
20 };
21
22 return proxy_socket_send_request(&client->socket, &req, sizeof(req));
23 }
24
25 bool
proxy_client_create_context(struct proxy_client * client,uint32_t ctx_id,size_t ctx_name_len,const char * ctx_name,int * out_ctx_fd)26 proxy_client_create_context(struct proxy_client *client,
27 uint32_t ctx_id,
28 size_t ctx_name_len,
29 const char *ctx_name,
30 int *out_ctx_fd)
31 {
32 struct render_client_op_create_context_request req = {
33 .header.op = RENDER_CLIENT_OP_CREATE_CONTEXT,
34 .ctx_id = ctx_id,
35 };
36
37 const size_t len = MIN2(ctx_name_len, sizeof(req.ctx_name) - 1);
38 memcpy(req.ctx_name, ctx_name, len);
39
40 if (!proxy_socket_send_request(&client->socket, &req, sizeof(req)))
41 return false;
42
43 struct render_client_op_create_context_reply reply;
44 int fd_count;
45 int ctx_fd;
46 if (!proxy_socket_receive_reply_with_fds(&client->socket, &reply, sizeof(reply),
47 &ctx_fd, 1, &fd_count))
48 return false;
49
50 if (reply.ok != fd_count) {
51 if (fd_count)
52 close(ctx_fd);
53 return false;
54 } else if (!reply.ok) {
55 return false;
56 }
57
58 if (!proxy_socket_is_seqpacket(ctx_fd)) {
59 close(ctx_fd);
60 return false;
61 }
62
63 *out_ctx_fd = ctx_fd;
64 return true;
65 }
66
67 bool
proxy_client_reset(struct proxy_client * client)68 proxy_client_reset(struct proxy_client *client)
69 {
70 const struct render_client_op_reset_request req = {
71 .header.op = RENDER_CLIENT_OP_RESET,
72 };
73 return proxy_socket_send_request(&client->socket, &req, sizeof(req));
74 }
75
76 void
proxy_client_destroy(struct proxy_client * client)77 proxy_client_destroy(struct proxy_client *client)
78 {
79 proxy_socket_fini(&client->socket);
80 free(client);
81 }
82
83 static bool
proxy_client_init(struct proxy_client * client,uint32_t flags)84 proxy_client_init(struct proxy_client *client, uint32_t flags)
85 {
86 const struct render_client_op_init_request req = {
87 .header.op = RENDER_CLIENT_OP_INIT,
88 .flags = flags,
89 };
90 return proxy_socket_send_request(&client->socket, &req, sizeof(req));
91 }
92
93 struct proxy_client *
proxy_client_create(struct proxy_server * srv,uint32_t flags)94 proxy_client_create(struct proxy_server *srv, uint32_t flags)
95 {
96 struct proxy_client *client = calloc(1, sizeof(*client));
97 if (!client)
98 return NULL;
99
100 const int client_fd = proxy_server_connect(srv);
101 if (client_fd < 0) {
102 free(client);
103 return NULL;
104 }
105
106 proxy_socket_init(&client->socket, client_fd);
107
108 if (!proxy_client_init(client, flags)) {
109 proxy_socket_fini(&client->socket);
110 free(client);
111 return NULL;
112 }
113
114 return client;
115 }
116