---
name: "r_socket"
section: "3"
platform: "linux"
package: "radare2"
version: "6.2.2-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/r_socket"
---

# r\_socket(3)

Network socket library for radare2

## 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;
    }
    while ((cli = r_socket_accept (s))) {
        r_socket_read (cli, (unsigned char *)buf, 9);
        strcpy (buf, "HTTP/1.0 200 OK0erver: EKRServer0r0erver test page0);
        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_core/3.md), [r\_util(3)](/r_util/3.md)
