Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
R_SOCKET(3)		     Library Functions Manual		     R_SOCKET(3)

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 conven-
     tions), 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 fail-
     ure.   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  re-
     turns 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 re-
     sponse 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  ac-
     cess 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_con-
     tinue ()` 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  com-
     mand)  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 interac-
     tions).

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 do-
     main 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 compo-
     nents 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)

FreeBSD ports 15.quarterly     September 21, 2025		     R_SOCKET(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=r_socket&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help