Provided by: radare2_6.0.4+dfsg-1_amd64 bug

NAME

       r_socket — Network socket library for radare2

SYNOPSIS

       #include <r_socket.h>

DESCRIPTION

       Networking and local process I/O used across radare2 is provided by the r_socket API. It exposes a small,
       portable  socket  wrapper  that supports plain TCP/UDP, SSL/TLS (when compiled with OpenSSL), Unix domain
       sockets, serial and virtual protocols (RAP and r2pipe). The API is intentionally small  so  higher  level
       components in the tree (for example `libr/core` and `libr/main`) can combine connect/listen, HTTP helpers
       and process pipes to implement r2web, r2agent and remote file access.

       The  main  opaque  type is struct r_socket_t, which holds the underlying file descriptor and optional SSL
       context when TLS is used.

INITIALIZATION

       Before using any socket operations allocate an `RSocket` and free it when finished. The constructor  lets
       callers  request  an SSL-capable socket; a socket created with `is_ssl=true` will attempt TLS negotiation
       on connect or accept when OpenSSL is available.

       Function signatures:

             RSocket *r_socket_new (bool is_ssl);
             RSocket *r_socket_new_from_fd (int fd);
             void r_socket_free (RSocket *s);

       `r_socket_new ()` never returns `NULL` (see project allocation conventions), but  the  socket  may  still
       fail to connect or bind. Use the free function to release sockets created with any constructor.

CONNECTIONS

       Establishing  an  outgoing connection is done with `r_socket_connect` or the provided convenience macros.
       The API supports a timeout parameter and a protocol selector so the same call surface  can  be  used  for
       TCP, UDP or Unix sockets.

       Function signatures:

             bool r_socket_connect (RSocket *s, const char *host, const char *port, int proto, unsigned int timeout);
             bool r_socket_connect_tcp (RSocket *s, const char *host, const char *port, unsigned int timeout);
             bool r_socket_connect_udp (RSocket *s, const char *host, const char *port, unsigned int timeout);
             int r_socket_connect_serial (RSocket *sock, const char *path, int speed, int parity);

       Return  value: these functions return `true` on success and `false` on failure. Timeouts are expressed in
       milliseconds for connect. Use `r_socket_is_connected ()` and `r_socket_ready ()` to  check  socket  state
       after connect if needed.

       When  using  SSL  sockets  created  with  `r_socket_new  (true)`,  TLS  negotiation  is  performed during
       `r_socket_connect ()` (client) or `r_socket_accept ()` (server) if OpenSSL is enabled at build time.

SERVERS

       To accept incoming connections create an `RSocket`, call `r_socket_listen` to  bind  the  port  and  then
       repeatedly accept clients. A server socket may be plain or TLS-enabled by passing a certificate file path
       to `r_socket_listen ()`.

       Function signatures:

             bool r_socket_listen (RSocket *s, const char *port, const char *certfile);
             RSocket *r_socket_accept (RSocket *s);
             RSocket *r_socket_accept_timeout (RSocket *s, unsigned int timeout);
             bool r_socket_close (RSocket *s);

       Typical  loop: call `r_socket_accept ()` (or the timeout variant) and handle the returned `RSocket *` for
       the client; free it when done. `r_socket_close` closes  the  underlying  listening  descriptor  when  the
       server should stop.

DATA TRANSFER

       Data transfer functions provide blocking and non-blocking reads/writes as well as convenience helpers for
       formatted output and line-oriented input.

       Function signatures:

             int r_socket_write (RSocket *s, const void *buf, int len);
             int r_socket_puts (RSocket *s, char *buf);
             void r_socket_printf (RSocket *s, const char *fmt, ...);
             int r_socket_read (RSocket *s, ut8 *read, int len);
             int r_socket_read_block (RSocket *s, unsigned char *buf, int len);
             int r_socket_gets (RSocket *s, char *buf, int size);
             int r_socket_flush (RSocket *s);
             ut8 *r_socket_slurp (RSocket *s, int *len);
             int r_socket_ready (RSocket *s, int secs, int usecs);
             bool r_socket_is_connected (RSocket *s);

       Notes: - `r_socket_gets ()` reads until newline (or buffer full) and returns the
         number of bytes read (or negative on error). Use it for simple line-based
         protocols  (for  example  debugging servers in tests).  - `r_socket_read_block ()` attempts to read the
       requested number of bytes;
         use it when an exact size is expected. Plain `r_socket_read ()` reads up to
         the provided buffer length and may return sooner.  - After sending a response on an accepted connection
       call `r_socket_flush ()`
         to ensure buffered data is written before closing the socket.  - Use `r_socket_ready ()`  to  poll  for
       readability/writability without busy
         looping.

HTTP CLIENT

       r_socket  contains  simple  HTTP client helpers used by several parts of radare2 to fetch small resources
       (for example `rtr` and plugin download helpers). These are intentionally  light-weight:  they  return  an
       allocated buffer with the full response body (no streaming API) and are convenient for short fetches.

       Function signatures:

             char *r_socket_http_get (const char *url, const char **headers, int *code, int *rlen);
             char *r_socket_http_post (const char *url, const char **headers, const char *data, int *code, int *rlen);

       Behaviour  and ownership: the returned pointer is malloc'd by the callee and must be freed by the caller.
       `code` receives the HTTP status code (when not NULL) and `rlen`  receives  the  length  of  the  returned
       buffer.  When  fetching  large  resources prefer other I/O hooks (for example `libr/io`) to avoid holding
       large blobs in memory.

RAP PROTOCOL

       The  RAP  protocol  is  a  compact  request/reply  protocol  used  to  expose  file  operations  remotely
       (open/read/write/seek).  radare2  exposes both server and client helpers that wrap RSocket so callers can
       implement remote file access or forward commands across a socket.

       Function signatures:

             RSocketRapServer *r_socket_rap_server_new (bool is_ssl, const char *port);
             RSocketRapServer *r_socket_rap_server_create (const char *pathname);
             void r_socket_rap_server_free (RSocketRapServer *rap_s);
             bool r_socket_rap_server_listen (RSocketRapServer *rap_s, const char *certfile);
             RSocket *r_socket_rap_server_accept (RSocketRapServer *rap_s);
             bool r_socket_rap_server_continue (RSocketRapServer *rap_s);

       Typical usage: create the server with `r_socket_rap_server_new ()`, call `r_socket_rap_server_listen  ()`
       and  loop while `r_socket_rap_server_continue ()` returns true. The RAP helpers allow implementing remote
       access to files or exposing r2 commands across a socket.

R2PIPE AND PROCESS PIPES

       r2pipe is a convenience layer built on top of the process pipe helpers in the socket  module.  It  allows
       spawning  a  radare2  process  (or any local command) and sending/receiving text commands via a pipe. The
       implementation uses `r_socket_proc_*` APIs under the hood.

       Function signatures:

             R2Pipe *r2pipe_open (const char *cmd);
             char *r2pipe_cmd (R2Pipe *r2pipe, const char *str);
             RSocketProc *r_socket_proc_open (char *const argv[]);
             int r_socket_proc_close (RSocketProc *sp);
             int r_socket_proc_read (RSocketProc *sp, unsigned char *buf, int len);
             int r_socket_proc_gets (RSocketProc *sp, char *buf, int size);
             int r_socket_proc_write (RSocketProc *sp, void *buf, int len);
             void r_socket_proc_printf (RSocketProc *sp, const char *fmt, ...);

       `r2pipe_cmd()` returns a malloc'd string that the caller must free. Use the `r_socket_proc_*`  primitives
       when  you need lower-level control over the child process I/O (for example non-blocking reads or scripted
       interactions).

PROTOCOLS

       The API exposes a small set of protocol constants to select the transport used by `r_socket_connect  ()`.
       Most  users  will  choose  TCP or UDP; unix domain sockets are used by local-only services and serial/CAN
       constants are present to support platform-specific backends.

       Supported protocol constants:

       R_SOCKET_PROTO_TCP   TCP connections

       R_SOCKET_PROTO_UDP   UDP datagrams

       R_SOCKET_PROTO_UNIX  Unix domain sockets

       R_SOCKET_PROTO_SERIAL
                            Serial connections

       R_SOCKET_PROTO_CAN   CAN bus (Linux only)

EXAMPLES

       The examples below are drawn from real test code and from how core components use the socket  APIs.  They
       illustrate   common   patterns:   simple   clients,  TLS-capable  servers  and  HTTP  handling  with  the
       `r_socket_http_*` helpers.

       Minimal TCP client (pattern from `test/unit/legacy_unit/socket/client.c`):

             #include <r_socket.h>

             int main(void) {
                 char buf[1024];
                 RSocket *s = r_socket_new (false);
                 if (r_socket_connect (s, "localhost", "9090", R_SOCKET_PROTO_TCP, 10000)) {
                     while (r_socket_gets (s, buf, sizeof (buf)) >= 0) {
                         eprintf ("((%s))0, buf);
                     }
                 }
                 r_socket_free (s);
                 return 0;
             }

       TLS  server  that  accepts  a  client  and   responds   with   a   simple   HTTP   page   (adapted   from
       `test/unit/legacy_unit/socket/serverssl.c`):

             #include <r_socket.h>
             #define PORT "4433"

             int main (int argc, char **argv) {
                 char buf[2048];
                 RSocket *s, *cli;
                 if (argc < 2) {
                     eprintf ("Use %s <cert>0, argv[0]);
                     return 1;
                 }
                 s = r_socket_new (true);
                 if (!r_socket_listen (s, PORT, argv[1])) {
                     eprintf ("Error, cant listen at port: %s0, PORT);
                     return 1;
                 }                                                                     0);
                 while ((cli = r_socket_accept (s))) {              0r10erver test page
                     r_socket_read (cli, (unsigned10erver:bEKRServer
                     strcpy (buf, "HTTP/1.0 200 OK
                     r_socket_write (cli, buf, strlen (buf));
                     r_socket_flush (cli);
                     r_socket_free (cli);
                 }
                 r_socket_free (s);
                 return 0;
             }

       HTTP server loop and reply (pattern used by `libr/core` HTTP handlers):

             RSocket *server = r_socket_new (false);
             if (r_socket_listen (server, "8080", NULL)) {
                 for (;;) {
                     RSocketHTTPRequest *req = r_socket_http_accept (server, NULL);
                     if (!req) { break; }
                     /* req->path, req->method and req->data are populated by the helper */
                     r_socket_http_response (req, 200, "Hello World", 0, NULL);
                     r_socket_http_free (req);
                 }
             }
             /* remember to close/free the listening socket when done */

SEE ALSO

       r_core(3), r_util(3)

Debian                                         September 21, 2025                                    R_SOCKET(3)