BRL-CAD
Loading...
Searching...
No Matches
fbserv.h
Go to the documentation of this file.
1/* F B S E R V . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2026 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20/** @addtogroup libdm */
21/** @{ */
22/** @file fbserv.h
23 *
24 * @brief
25 * This header holds generic routines and data structures used for TCP based
26 * (and, via libpkg, local-IPC based) communication between a framebuffer and a
27 * remote process. Variations on this logic, based originally on the
28 * stand-alone fbserv program, are at the core of MGED and Archer's ability to
29 * display incoming image data from a separate rt process.
30 *
31 * Asynchronous interprocess communication and event monitoring is (as of 2021)
32 * still very much platform and toolkit specific. Hence, these data structures
33 * contain some void pointers which are used by individual applications to
34 * connect their own specific methods (for example, Tcl_Channel) to handle this
35 * problem. Improving this to be more generic and less dependent on specific
36 * toolkits and/or platform mechanisms would be a laudable goal, if practical.
37 *
38 * pkg IPC path (fbs_open_ipc):
39 * Instead of binding a TCP listen socket, creates a pkg_pair() and
40 * immediately wraps the parent end as a pre-connected pkg_conn client.
41 * The child-end address is retrieved via fbs_ipc_child_addr_env() and
42 * passed to the spawned rt subprocess via the PKG_ADDR environment
43 * variable (set with bu_setenv() before the fork, cleared after).
44 *
45 */
46
47#ifndef DM_FBSERV_H
48#define DM_FBSERV_H
49
50#include "common.h"
51#include "pkg.h"
52#include "dm/defines.h"
53
55
56/* Framebuffer server object */
57
58#define NET_LONG_LEN 4 /**< @brief # bytes to network long */
59#define MAX_CLIENTS 32
60#define MAX_PORT_TRIES 100
61#define FBS_CALLBACK_NULL (void (*)(void))NULL
62#define FBSERV_OBJ_NULL (struct fbserv_obj *)NULL
63
64struct fbserv_obj;
65
67 int fbsl_fd; /**< @brief socket fd to listen for connections (copy of listener fd) */
68 void *fbsl_chan; /**< @brief platform/toolkit specific channel */
69 int fbsl_port; /**< @brief port number to listen on */
70 int fbsl_listen; /**< @brief !0 means listen for connections */
71 struct fbserv_obj *fbsl_fbsp; /**< @brief points to its fbserv object */
72 struct pkg_conn *fbsl_ipc_child; /**< @brief IPC child-end channel (NULL when using TCP) */
73 struct pkg_listener *fbsl_listener; /**< @brief TCP listener (NULL when using IPC or Tcl channel) */
74};
75
76
78 int fbsc_fd; /**< @brief socket to send data down */
79 void *fbsc_chan; /**< @brief platform/toolkit specific channel */
80 void *fbsc_handler; /**< @brief platform/toolkit specific handler */
82 struct fbserv_obj *fbsc_fbsp; /**< @brief points to its fbserv object */
83 int fbsc_auth_ok; /**< @brief !0 = client has sent a valid MSG_FBAUTH */
84 int fbsc_pending_drop; /**< @brief !0 = drop this client after pkg_process() returns */
85 int fbsc_is_ipc; /**< @brief !0 = client is connected via IPC (not TCP) */
86};
87
88
89struct fbserv_obj {
90 struct fb *fbs_fbp; /**< @brief framebuffer pointer */
91 void *fbs_interp; /**< @brief interpreter */
92 struct fbserv_listener fbs_listener; /**< @brief data for listening */
93 struct fbserv_client fbs_clients[MAX_CLIENTS]; /**< @brief connected clients */
94
95 int (*fbs_is_listening)(struct fbserv_obj *); /**< @brief return 1 if listening, else 0 */
96 int (*fbs_listen_on_port)(struct fbserv_obj *, int); /**< @brief return 1 on success, 0 on failure */
97 void (*fbs_open_server_handler)(struct fbserv_obj *); /**< @brief platform/toolkit method to open listener handler */
98 void (*fbs_close_server_handler)(struct fbserv_obj *); /**< @brief platform/toolkit method to close handler listener */
99 void (*fbs_open_client_handler)(struct fbserv_obj *, int, void *); /**< @brief platform/toolkit specific client handler setup (called by fbs_new_client) */
100 void (*fbs_close_client_handler)(struct fbserv_obj *, int); /**< @brief platform/toolkit method to close handler for client at index client_id */
101 /**
102 * @brief Optional IPC-specific client open handler.
103 *
104 * When non-NULL, called by fbs_open_ipc() instead of fbs_open_client_handler
105 * for clients whose connection was established via IPC (pipe/socketpair).
106 * The toolkit-specific TCP client setup (e.g. QTcpSocket connections) is
107 * not appropriate for IPC clients; this handler installs fd-based I/O
108 * monitoring instead (e.g. Tcl_CreateFileHandler, QSocketNotifier).
109 *
110 * May be NULL, in which case fbs_open_client_handler is used (callers must
111 * ensure that handler tolerates NULL data).
112 */
113 void (*fbs_open_ipc_client_handler)(struct fbserv_obj *, int, void *);
114 /**
115 * @brief Optional IPC-specific client close handler (mirrors fbs_close_client_handler).
116 *
117 * When non-NULL, called by drop_client() for IPC clients (fbsc_is_ipc != 0).
118 * May be NULL, in which case fbs_close_client_handler is used.
119 */
121
122 void (*fbs_callback)(void *); /**< @brief callback function */
124 struct bu_vls *msgs;
125 int fbs_mode; /**< @brief 0-off, 1-underlay, 2-interlay, 3-overlay */
126
127 char fbs_auth_token[65]; /**< @brief session token (64 hex chars + NUL); empty = no auth required */
128 int fbs_require_auth; /**< @brief !0 = reject clients that don't send MSG_FBAUTH */
129 void *fbs_tls_ctx; /**< @brief opaque SSL_CTX* for TLS; NULL = no TLS */
130};
131
132DM_EXPORT extern int fbs_open(struct fbserv_obj *fbsp, int port);
133DM_EXPORT extern int fbs_close(struct fbserv_obj *fbsp);
136DM_EXPORT extern int fbs_new_client(struct fbserv_obj *fbsp, struct pkg_conn *pcp, void *data);
138
139/**
140 * @brief Open an IPC-based framebuffer server (no TCP listen socket).
141 *
142 * Creates a pkg_pair(), wraps the parent end as a pre-connected pkg_conn
143 * client (bypassing the TCP accept loop entirely), and registers it via
144 * fbs_open_ipc_client_handler (or fbs_open_client_handler if the former is
145 * NULL). The child end's address is stored in fbsp->fbs_listener.fbsl_ipc_child
146 * and can be retrieved with fbs_ipc_child_addr_env().
147 *
148 * Callers should:
149 * 1. Call fbs_open_ipc() to start the server.
150 * 2. Call fbs_ipc_child_addr_env() to get "PKG_ADDR=<addr>".
151 * 3. Set that variable in the parent env (bu_setenv) before spawning rt.
152 * 4. Clear the variable after bu_process_create() returns.
153 * 5. Pass "-F 0" (or any port spec) to rt so it opens a remote framebuffer;
154 * if_remote.c will detect PKG_ADDR and use the IPC channel instead.
155 *
156 * The child end is closed (pkg_close) when fbs_close() is called.
157 *
158 * @return BRLCAD_OK on success, BRLCAD_ERROR if pkg_pair fails.
159 */
161
162/**
163 * @brief Return the "PKG_ADDR=<addr>" env string for the spawned child.
164 *
165 * Valid after a successful fbs_open_ipc() call and until fbs_close() is
166 * called. Returns NULL if no IPC channel is active.
167 *
168 * The string is owned by the internal channel struct and must not be freed
169 * by the caller.
170 */
172
173/**
174 * Initialise @p fbsp->fbs_auth_token for session authentication.
175 *
176 * If the FBSERV_TOKEN environment variable is already set to a valid
177 * 64-hex-char token, that value is used directly so that the hosting
178 * application can pre-supply a known token and pass the same value to
179 * child processes (e.g. set FBSERV_TOKEN before execing rt/pix-fb).
180 * Token authentication works regardless of whether TLS is enabled.
181 *
182 * If FBSERV_TOKEN is not set or is the wrong length, a fresh random
183 * 256-bit token is generated. Falls back to /dev/urandom or a
184 * time+PID PRNG when OpenSSL is not available.
185 *
186 * Call this before fbs_open() so the token is ready for the first
187 * connecting client. Returns a pointer to fbsp->fbs_auth_token.
188 */
189DM_EXPORT extern const char *fbs_generate_token(struct fbserv_obj *fbsp);
190
191
193
194#endif /* DM_FBSERV_H */
195/** @} */
196/*
197 * Local Variables:
198 * mode: C
199 * tab-width: 8
200 * indent-tabs-mode: t
201 * c-file-style: "stroustrup"
202 * End:
203 * ex: shiftwidth=4 tabstop=8
204 */
Definition dvec.h:74
Header file for the BRL-CAD common definitions.
const char * fbs_ipc_child_addr_env(struct fbserv_obj *fbsp)
Return the "PKG_ADDR=<addr>" env string for the spawned child.
struct pkg_switch * fbs_pkg_switch(void)
#define MAX_CLIENTS
Definition fbserv.h:59
int fbs_new_client(struct fbserv_obj *fbsp, struct pkg_conn *pcp, void *data)
int fbs_close(struct fbserv_obj *fbsp)
void fbs_setup_socket(int fd)
void fbs_existing_client_handler(void *clientData, int mask)
const char * fbs_generate_token(struct fbserv_obj *fbsp)
int fbs_open(struct fbserv_obj *fbsp, int port)
int fbs_open_ipc(struct fbserv_obj *fbsp)
Open an IPC-based framebuffer server (no TCP listen socket).
Definition vls.h:53
Definition defines.h:75
int fbsc_pending_drop
!0 = drop this client after pkg_process() returns
Definition fbserv.h:84
struct fbserv_obj * fbsc_fbsp
points to its fbserv object
Definition fbserv.h:82
struct pkg_conn * fbsc_pkg
Definition fbserv.h:81
int fbsc_auth_ok
!0 = client has sent a valid MSG_FBAUTH
Definition fbserv.h:83
void * fbsc_chan
platform/toolkit specific channel
Definition fbserv.h:79
int fbsc_fd
socket to send data down
Definition fbserv.h:78
int fbsc_is_ipc
!0 = client is connected via IPC (not TCP)
Definition fbserv.h:85
void * fbsc_handler
platform/toolkit specific handler
Definition fbserv.h:80
struct pkg_conn * fbsl_ipc_child
IPC child-end channel (NULL when using TCP)
Definition fbserv.h:72
struct fbserv_obj * fbsl_fbsp
points to its fbserv object
Definition fbserv.h:71
int fbsl_port
port number to listen on
Definition fbserv.h:69
struct pkg_listener * fbsl_listener
TCP listener (NULL when using IPC or Tcl channel)
Definition fbserv.h:73
void * fbsl_chan
platform/toolkit specific channel
Definition fbserv.h:68
int fbsl_fd
socket fd to listen for connections (copy of listener fd)
Definition fbserv.h:67
int fbsl_listen
!0 means listen for connections
Definition fbserv.h:70
char fbs_auth_token[65]
session token (64 hex chars + NUL); empty = no auth required
Definition fbserv.h:127
void(* fbs_open_server_handler)(struct fbserv_obj *)
platform/toolkit method to open listener handler
Definition fbserv.h:97
struct fbserv_client fbs_clients[MAX_CLIENTS]
connected clients
Definition fbserv.h:93
void(* fbs_callback)(void *)
callback function
Definition fbserv.h:122
int(* fbs_listen_on_port)(struct fbserv_obj *, int)
return 1 on success, 0 on failure
Definition fbserv.h:96
struct bu_vls * msgs
Definition fbserv.h:124
void(* fbs_close_server_handler)(struct fbserv_obj *)
platform/toolkit method to close handler listener
Definition fbserv.h:98
void(* fbs_close_ipc_client_handler)(struct fbserv_obj *, int)
Optional IPC-specific client close handler (mirrors fbs_close_client_handler).
Definition fbserv.h:120
void * fbs_clientData
Definition fbserv.h:123
struct fbserv_listener fbs_listener
data for listening
Definition fbserv.h:92
int fbs_mode
0-off, 1-underlay, 2-interlay, 3-overlay
Definition fbserv.h:125
void(* fbs_close_client_handler)(struct fbserv_obj *, int)
platform/toolkit method to close handler for client at index client_id
Definition fbserv.h:100
int fbs_require_auth
!0 = reject clients that don't send MSG_FBAUTH
Definition fbserv.h:128
struct fb * fbs_fbp
framebuffer pointer
Definition fbserv.h:90
void * fbs_tls_ctx
opaque SSL_CTX* for TLS; NULL = no TLS
Definition fbserv.h:129
void * fbs_interp
interpreter
Definition fbserv.h:91
void(* fbs_open_ipc_client_handler)(struct fbserv_obj *, int, void *)
Optional IPC-specific client open handler.
Definition fbserv.h:113
void(* fbs_open_client_handler)(struct fbserv_obj *, int, void *)
platform/toolkit specific client handler setup (called by fbs_new_client)
Definition fbserv.h:99
int(* fbs_is_listening)(struct fbserv_obj *)
return 1 if listening, else 0
Definition fbserv.h:95
Definition pkg.h:81