Rizin
unix-like reverse engineering framework and cli tools
socket.c File Reference
#include <rz_socket.h>
#include <rz_types.h>
#include <rz_util.h>
#include <errno.h>

Go to the source code of this file.

Macros

#define NETWORK_DISABLED   0
 
#define D   if (0)
 
#define BUFFER_SIZE   4096
 

Functions

 RZ_LIB_VERSION (rz_socket)
 
RZ_API bool rz_socket_is_connected (RzSocket *s)
 
RZ_API RzSocketrz_socket_new (bool is_ssl)
 
RZ_API bool rz_socket_spawn (RzSocket *s, const char *cmd, unsigned int timeout)
 
RZ_API bool rz_socket_connect (RzSocket *s, const char *host, const char *port, int proto, unsigned int timeout)
 
RZ_API int rz_socket_close_fd (RzSocket *s)
 
RZ_API int rz_socket_close (RzSocket *s)
 
RZ_API int rz_socket_free (RzSocket *s)
 
RZ_API int rz_socket_port_by_name (const char *name)
 
RZ_API bool rz_socket_listen (RzSocket *s, const char *port, const char *certfile)
 
RZ_API RzSocketrz_socket_accept (RzSocket *s)
 
RZ_API RzSocketrz_socket_accept_timeout (RzSocket *s, unsigned int timeout)
 
RZ_API bool rz_socket_block_time (RzSocket *s, bool block, int sec, int usec)
 
RZ_API int rz_socket_flush (RzSocket *s)
 
RZ_API int rz_socket_ready (RzSocket *s, int secs, int usecs)
 
RZ_API char * rz_socket_to_string (RzSocket *s)
 
RZ_API int rz_socket_write (RzSocket *s, void *buf, int len)
 
RZ_API int rz_socket_puts (RzSocket *s, char *buf)
 
RZ_API void rz_socket_printf (RzSocket *s, const char *fmt,...)
 
RZ_API int rz_socket_read (RzSocket *s, unsigned char *buf, int len)
 
RZ_API int rz_socket_read_block (RzSocket *s, ut8 *buf, int len)
 
RZ_API int rz_socket_gets (RzSocket *s, char *buf, int size)
 
RZ_API RzSocketrz_socket_new_from_fd (int fd)
 
RZ_API ut8rz_socket_slurp (RzSocket *s, int *len)
 

Macro Definition Documentation

◆ BUFFER_SIZE

#define BUFFER_SIZE   4096

Definition at line 99 of file socket.c.

◆ D

#define D   if (0)

Definition at line 16 of file socket.c.

◆ NETWORK_DISABLED

#define NETWORK_DISABLED   0

Definition at line 13 of file socket.c.

Function Documentation

◆ RZ_LIB_VERSION()

RZ_LIB_VERSION ( rz_socket  )

◆ rz_socket_accept()

RZ_API RzSocket* rz_socket_accept ( RzSocket s)

Definition at line 582 of file socket.c.

582  {
583  RzSocket *sock;
584  socklen_t salen = sizeof(s->sa);
585  if (!s) {
586  return NULL;
587  }
588  sock = RZ_NEW0(RzSocket);
589  if (!sock) {
590  return NULL;
591  }
592  // signal (SIGPIPE, SIG_DFL);
593  sock->fd = accept(s->fd, (struct sockaddr *)&s->sa, &salen);
594  if (sock->fd == RZ_INVALID_SOCKET) {
595  if (errno != EWOULDBLOCK) {
596  // not just a timeout
597  rz_sys_perror("accept");
598  }
599  free(sock);
600  return NULL;
601  }
602 #if HAVE_LIB_SSL
603  sock->is_ssl = s->is_ssl;
604  if (sock->is_ssl) {
605  sock->sfd = NULL;
606  sock->ctx = NULL;
607  sock->bio = NULL;
608  BIO *sbio = BIO_new_socket(sock->fd, BIO_NOCLOSE);
609  sock->sfd = SSL_new(s->ctx);
610  SSL_set_bio(sock->sfd, sbio, sbio);
611  if (SSL_accept(sock->sfd) <= 0) {
612  rz_socket_free(sock);
613  return NULL;
614  }
615  sock->bio = BIO_new(BIO_f_buffer());
616  sbio = BIO_new(BIO_f_ssl());
617  BIO_set_ssl(sbio, sock->sfd, BIO_CLOSE);
618  BIO_push(sock->bio, sbio);
619  }
620 #else
621  sock->is_ssl = 0;
622 #endif
623  return sock;
624 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset void static length char static len const struct iovec static count unsigned long static filedes static sched_yield static flags static oldfd static pause unsigned static seconds static protocol accept
Definition: sflib.h:75
static RzSocket * s
Definition: rtr.c:28
#define RZ_INVALID_SOCKET
Definition: rz_socket.h:48
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define RZ_NEW0(x)
Definition: rz_types.h:284
unsigned int socklen_t
Definition: sftypes.h:219
RZ_API int rz_socket_free(RzSocket *s)
Definition: socket.c:453
bool is_ssl
Definition: rz_socket.h:68
struct sockaddr_in sa
Definition: rz_socket.h:72

References accept, rz_socket_t::fd, free(), rz_socket_t::is_ssl, NULL, RZ_INVALID_SOCKET, RZ_NEW0, rz_socket_free(), rz_sys_perror, s, and rz_socket_t::sa.

Referenced by rz_core_rtr_cmds(), rz_core_rtr_gdb_run(), rz_core_serve(), rz_run_config_env(), rz_socket_accept_timeout(), rz_socket_http_accept(), rz_socket_rap_server_accept(), rz_write_from_socket_handler(), and tcpme().

◆ rz_socket_accept_timeout()

RZ_API RzSocket* rz_socket_accept_timeout ( RzSocket s,
unsigned int  timeout 
)

Definition at line 626 of file socket.c.

626  {
627  fd_set read_fds;
628  fd_set except_fds;
629 
630  FD_ZERO(&read_fds);
631  FD_SET(s->fd, &read_fds);
632 
633  FD_ZERO(&except_fds);
634  FD_SET(s->fd, &except_fds);
635 
636  struct timeval t = { timeout, 0 };
637 
638  int r = select(s->fd + 1, &read_fds, NULL, &except_fds, &t);
639  if (r < 0) {
640  perror("select");
641  } else if (r > 0 && FD_ISSET(s->fd, &read_fds)) {
642  return rz_socket_accept(s);
643  }
644 
645  return NULL;
646 }
#define r
Definition: crypto_rc6.c:12
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz select
Definition: sflib.h:108
#define FD_ZERO(set)
Definition: sftypes.h:204
#define FD_ISSET(d, set)
Definition: sftypes.h:214
#define FD_SET(d, set)
Definition: sftypes.h:212
RZ_API RzSocket * rz_socket_accept(RzSocket *s)
Definition: socket.c:582
uv_timer_t timeout
Definition: main.c:9

References rz_socket_t::fd, FD_ISSET, FD_SET, FD_ZERO, NULL, r, rz_socket_accept(), s, select, and timeout.

Referenced by rz_socket_http_accept().

◆ rz_socket_block_time()

RZ_API bool rz_socket_block_time ( RzSocket s,
bool  block,
int  sec,
int  usec 
)

Definition at line 649 of file socket.c.

649  {
650 #if __UNIX__
651  int ret, flags;
652 #endif
653  if (!s) {
654  return false;
655  }
656 #if __UNIX__
657  flags = fcntl(s->fd, F_GETFL, 0);
658  if (flags < 0) {
659  return false;
660  }
661  ret = fcntl(s->fd, F_SETFL, block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK));
662  if (ret < 0) {
663  return false;
664  }
665 #elif __WINDOWS__
666  ioctlsocket(s->fd, FIONBIO, (u_long FAR *)&block);
667 #endif
668  if (sec > 0 || usec > 0) {
669  struct timeval tv = { sec, usec };
670  if (setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) < 0) {
671  return false;
672  }
673  }
674  return true;
675 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval tv
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags fcntl
Definition: sflib.h:79
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define F_GETFL
Definition: sftypes.h:506
#define O_NONBLOCK
Definition: sftypes.h:494
#define SOL_SOCKET
Definition: sftypes.h:427
#define F_SETFL
Definition: sftypes.h:507
#define SO_RCVTIMEO
Definition: sftypes.h:448
#define FIONBIO
Definition: sftypes.h:736
#define FAR
Definition: zconf.h:387

References F_GETFL, F_SETFL, FAR, fcntl, rz_socket_t::fd, FIONBIO, flags, O_NONBLOCK, s, SO_RCVTIMEO, SOL_SOCKET, and tv.

Referenced by runcmd(), rz_socket_connect(), rz_socket_http_accept(), rz_socket_is_connected(), rz_socket_rap_client_open(), rz_socket_rap_client_read(), and socket_slurp().

◆ rz_socket_close()

RZ_API int rz_socket_close ( RzSocket s)

Definition at line 419 of file socket.c.

419  {
420  int ret = false;
421  if (!s) {
422  return false;
423  }
424  if (s->fd != RZ_INVALID_SOCKET) {
425 #if __UNIX__
426  shutdown(s->fd, SHUT_RDWR);
427 #endif
428 #if __WINDOWS__
429  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms740481(v=vs.85).aspx
430  shutdown(s->fd, SD_SEND);
431  if (rz_socket_ready(s, 0, 250)) {
432  do {
433  char buf = 0;
434  ret = recv(s->fd, &buf, 1, 0);
435  } while (ret != 0 && ret != SOCKET_ERROR);
436  }
437  ret = closesocket(s->fd);
438 #else
439  ret = close(s->fd);
440 #endif
442  }
443 #if HAVE_LIB_SSL
444  if (s->is_ssl && s->sfd) {
445  SSL_free(s->sfd);
446  s->sfd = NULL;
447  }
448 #endif
449  return ret;
450 }
static static fork const void static count close
Definition: sflib.h:33
voidpf void * buf
Definition: ioapi.h:138
#define SD_SEND
Definition: rz_socket.h:41
RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs)
Definition: socket.c:688

References close, rz_socket_t::fd, rz_socket_t::is_ssl, NULL, RZ_INVALID_SOCKET, rz_socket_ready(), s, and SD_SEND.

Referenced by __rap_close(), gdbr_connect(), gdbr_disconnect(), iob_net_close(), qnxr_disconnect(), rap_break(), rz_core_rtr_cmd(), rz_core_rtr_cmds(), rz_core_rtr_gdb_run(), rz_core_serve(), rz_socket_connect(), rz_socket_free(), rz_socket_gets(), rz_socket_rap_server_continue(), rz_socket_spawn(), and socket_http_answer().

◆ rz_socket_close_fd()

RZ_API int rz_socket_close_fd ( RzSocket s)

Definition at line 410 of file socket.c.

410  {
411 #ifdef _MSC_VER
412  return s->fd != INVALID_SOCKET ? closesocket(s->fd) : false;
413 #else
414  return s->fd != -1 ? close(s->fd) : false;
415 #endif
416 }
#define false

References close, rz_socket_t::fd, and s.

Referenced by redirect_socket_to_pty(), and rz_run_config_env().

◆ rz_socket_connect()

RZ_API bool rz_socket_connect ( RzSocket s,
const char *  host,
const char *  port,
int  proto,
unsigned int  timeout 
)

Definition at line 257 of file socket.c.

257  {
258  rz_return_val_if_fail(s, false);
259 #if __WINDOWS__
260 #define gai_strerror gai_strerrorA
261  WSADATA wsadata;
262 
263  if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) {
264  eprintf("Error creating socket.");
265  return false;
266  }
267 #endif
268  int ret;
269  struct addrinfo hints = { 0 };
270  struct addrinfo *res, *rp;
271  if (proto == RZ_SOCKET_PROTO_NONE) {
272  proto = RZ_SOCKET_PROTO_DEFAULT;
273  }
274 #if __UNIX__
275  rz_sys_signal(SIGPIPE, SIG_IGN);
276 #endif
277  if (proto == RZ_SOCKET_PROTO_UNIX) {
278 #if __UNIX__
279  if (!__connect_unix(s, host)) {
280  return false;
281  }
282 #endif
283  } else {
284  hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
285  hints.ai_protocol = proto;
286  int gai = getaddrinfo(host, port, &hints, &res);
287  if (gai != 0) {
288  eprintf("rz_socket_connect: Error in getaddrinfo: %s (%s:%s)\n",
289  gai_strerror(gai), host, port);
290  return false;
291  }
292  for (rp = res; rp != NULL; rp = rp->ai_next) {
293  int flag = 1;
294 
295  s->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
296  if (s->fd == -1) {
297  perror("socket");
298  continue;
299  }
300 
301  switch (proto) {
302  case RZ_SOCKET_PROTO_TCP:
303  ret = setsockopt(s->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
304  if (ret < 0) {
305  perror("setsockopt");
306  close(s->fd);
307  s->fd = -1;
308  continue;
309  }
310  rz_socket_block_time(s, true, 1, 0);
311  ret = connect(s->fd, rp->ai_addr, rp->ai_addrlen);
312  break;
313  case RZ_SOCKET_PROTO_UDP:
314  memset(&s->sa, 0, sizeof(s->sa));
315  s->sa.sin_family = AF_INET;
316  s->sa.sin_addr.s_addr = htonl(s->local ? INADDR_LOOPBACK : INADDR_ANY);
317  s->port = rz_socket_port_by_name(port);
318  if (s->port < 1) {
319  continue;
320  }
321  s->sa.sin_port = htons(s->port);
322  if (bind(s->fd, (struct sockaddr *)&s->sa, sizeof(s->sa)) < 0) {
323  rz_sys_perror("bind");
324 #ifdef __WINDOWS__
325  closesocket(s->fd);
326 #else
327  close(s->fd);
328 #endif
329  continue;
330  }
331  ret = connect(s->fd, rp->ai_addr, rp->ai_addrlen);
332  break;
333  default:
334  rz_socket_block_time(s, true, 1, 0);
335  ret = connect(s->fd, rp->ai_addr, rp->ai_addrlen);
336  break;
337  }
338 
339  if (ret == 0) {
340  freeaddrinfo(res);
341  return true;
342  }
343  if (errno == EINPROGRESS) {
344  struct timeval tv = { timeout, 0 };
345  fd_set wfds;
346  FD_ZERO(&wfds);
347  FD_SET(s->fd, &wfds);
348 
349  if (select(s->fd + 1, NULL, &wfds, NULL, &tv) != -1) {
350  if (rz_socket_is_connected(s)) {
351  freeaddrinfo(res);
352  goto success;
353  }
354  } else {
355  perror("connect");
356  }
357  }
359  }
360  freeaddrinfo(res);
361  if (!rp) {
362  eprintf("Could not resolve address '%s' or failed to connect\n", host);
363  return false;
364  }
365  }
366 success:
367 #if HAVE_LIB_SSL
368  if (s->is_ssl) {
369  s->ctx = SSL_CTX_new(SSLv23_client_method());
370  if (!s->ctx) {
372  return false;
373  }
374  s->sfd = SSL_new(s->ctx);
375  SSL_set_fd(s->sfd, s->fd);
376  int ret = SSL_connect(s->sfd);
377  if (ret != 1) {
378  int error = SSL_get_error(s->sfd, ret);
379  int tries = 10;
380  while (tries && ret && (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)) {
381  struct timeval tv = { 1, 0 };
382  fd_set rfds, wfds;
383  FD_ZERO(&rfds);
384  FD_ZERO(&wfds);
385  if (error == SSL_ERROR_WANT_READ) {
386  FD_SET(s->fd, &rfds);
387  } else {
388  FD_SET(s->fd, &wfds);
389  }
390  if ((ret = select(s->fd + 1, &rfds, &wfds, NULL, &tv)) < 1) {
392  return false;
393  }
394  ret = SSL_connect(s->sfd);
395  if (ret == 1) {
396  return true;
397  }
398  error = SSL_get_error(s->sfd, ret);
399  tries--;
400  }
402  return false;
403  }
404  }
405 #endif
406  return true;
407 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd socket
Definition: sflib.h:79
static char * rp[]
Definition: i8080dis.c:36
return memset(p, 0, total)
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_SOCKET_PROTO_NONE
Definition: rz_socket.h:90
#define RZ_SOCKET_PROTO_UNIX
Definition: rz_socket.h:89
#define RZ_SOCKET_PROTO_UDP
Definition: rz_socket.h:88
#define RZ_SOCKET_PROTO_TCP
Definition: rz_socket.h:87
#define RZ_SOCKET_PROTO_DEFAULT
Definition: rz_socket.h:91
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
Definition: sys.c:178
static bind
Definition: sfsocketcall.h:114
#define htons(x)
Definition: sftypes.h:475
#define EINPROGRESS
Definition: sftypes.h:175
#define AF_INET
Definition: sftypes.h:287
#define AF_UNSPEC
Definition: sftypes.h:283
RZ_API bool rz_socket_is_connected(RzSocket *s)
Definition: socket.c:101
RZ_API int rz_socket_close(RzSocket *s)
Definition: socket.c:419
RZ_API int rz_socket_port_by_name(const char *name)
Definition: socket.c:469
RZ_API bool rz_socket_block_time(RzSocket *s, bool block, int sec, int usec)
Definition: socket.c:649
in_addr_t s_addr
Definition: sftypes.h:337
struct in_addr sin_addr
Definition: sftypes.h:344
in_port_t sin_port
Definition: sftypes.h:343
void error(const char *msg)
Definition: untgz.c:593

References AF_INET, AF_UNSPEC, bind, close, EINPROGRESS, eprintf, error(), rz_socket_t::fd, FD_SET, FD_ZERO, htons, rz_socket_t::is_ssl, rz_socket_t::local, memset(), NULL, rz_socket_t::port, rp, rz_return_val_if_fail, rz_socket_block_time(), rz_socket_close(), rz_socket_is_connected(), rz_socket_port_by_name(), RZ_SOCKET_PROTO_DEFAULT, RZ_SOCKET_PROTO_NONE, RZ_SOCKET_PROTO_TCP, RZ_SOCKET_PROTO_UDP, RZ_SOCKET_PROTO_UNIX, rz_sys_perror, rz_sys_signal(), s, in_addr::s_addr, rz_socket_t::sa, select, sockaddr_in::sin_addr, sockaddr_in::sin_port, socket, timeout, and tv.

Referenced by __rap_open(), rz_core_rtr_cmd(), rz_core_rtr_cmds_query(), rz_core_rtr_http_stop(), rz_socket_spawn(), and tcpme().

◆ rz_socket_flush()

RZ_API int rz_socket_flush ( RzSocket s)

Definition at line 677 of file socket.c.

677  {
678 #if HAVE_LIB_SSL
679  if (s->is_ssl && s->bio) {
680  return BIO_flush(s->bio);
681  }
682 #endif
683  return true;
684 }

References rz_socket_t::is_ssl, and s.

Referenced by __rap_system(), rz_core_serve(), rz_socket_rap_client_command(), rz_socket_rap_client_open(), rz_socket_rap_client_read(), rz_socket_rap_client_seek(), rz_socket_rap_client_write(), and rz_socket_rap_server_continue().

◆ rz_socket_free()

◆ rz_socket_gets()

RZ_API int rz_socket_gets ( RzSocket s,
char *  buf,
int  size 
)

Definition at line 830 of file socket.c.

830  {
831  int i = 0;
832  int ret = 0;
833 
834  if (s->fd == RZ_INVALID_SOCKET) {
835  return -1;
836  }
837  while (i < size) {
838  ret = rz_socket_read(s, (ut8 *)buf + i, 1);
839  if (ret == 0) {
840  if (i > 0) {
841  return i;
842  }
843  return -1;
844  }
845  if (ret < 0) {
847  return i == 0 ? -1 : i;
848  }
849  if (buf[i] == '\r' || buf[i] == '\n') {
850  buf[i] = 0;
851  break;
852  }
853  i += ret;
854  }
855  buf[i] = '\0';
856  return i;
857 }
lzma_index ** i
Definition: index.h:629
voidpf void uLong size
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API int rz_socket_read(RzSocket *s, unsigned char *buf, int len)
Definition: socket.c:783

References rz_socket_t::fd, i, RZ_INVALID_SOCKET, rz_socket_close(), rz_socket_read(), and s.

Referenced by rz_socket_http_accept(), and rz_socket_proc_gets().

◆ rz_socket_is_connected()

RZ_API bool rz_socket_is_connected ( RzSocket s)

Definition at line 101 of file socket.c.

101  {
102 #if __WINDOWS__
103  char buf[2];
104  rz_socket_block_time(s, false, 0, 0);
105 #ifdef _MSC_VER
106  int ret = recv(s->fd, (char *)&buf, 1, MSG_PEEK);
107 #else
108  ssize_t ret = recv(s->fd, (char *)&buf, 1, MSG_PEEK);
109 #endif
110  rz_socket_block_time(s, true, 0, 0);
111  return ret == 1;
112 #else
113  int error = 0;
114  socklen_t len = sizeof(error);
115  int ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &error, &len);
116  if (ret != 0) {
117  perror("getsockopt");
118  return false;
119  }
120  return (error == 0);
121 #endif
122 }
size_t len
Definition: 6502dis.c:15
#define SO_ERROR
Definition: sftypes.h:432
int ssize_t
Definition: sftypes.h:39

References error(), rz_socket_t::fd, len, rz_socket_block_time(), s, SO_ERROR, and SOL_SOCKET.

Referenced by rz_socket_connect(), rz_socket_rap_server_continue(), and send_vcont().

◆ rz_socket_listen()

RZ_API bool rz_socket_listen ( RzSocket s,
const char *  port,
const char *  certfile 
)

Definition at line 474 of file socket.c.

474  {
475  int optval = 1;
476  int ret;
477  struct linger linger = { 0 };
478 
479  if (s->proto == RZ_SOCKET_PROTO_UNIX) {
480 #if __UNIX__
481  return __listen_unix(s, port);
482 #endif
483  return false;
484  }
485 
486 #if __WINDOWS__
487  WSADATA wsadata;
488  if (WSAStartup(MAKEWORD(1, 1), &wsadata) == SOCKET_ERROR) {
489  eprintf("Error creating socket.");
490  return false;
491  }
492 #endif
493  if (s->proto == RZ_SOCKET_PROTO_NONE) {
495  }
496  switch (s->proto) {
497  case RZ_SOCKET_PROTO_TCP:
499  return false;
500  }
501  break;
502  case RZ_SOCKET_PROTO_UDP:
504  return false;
505  }
506  break;
507  default:
508  eprintf("Invalid protocol for socket\n");
509  return false;
510  }
511 
512  linger.l_onoff = 1;
513  linger.l_linger = 1;
514  ret = setsockopt(s->fd, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
515  if (ret < 0) {
516  return false;
517  }
518  { // fix close after write bug //
519  int x = 1500; // FORCE MTU
520  ret = setsockopt(s->fd, SOL_SOCKET, SO_SNDBUF, (void *)&x, sizeof(int));
521  if (ret < 0) {
522  return false;
523  }
524  }
525  ret = setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof optval);
526  if (ret < 0) {
527  return false;
528  }
529 
530  memset(&s->sa, 0, sizeof(s->sa));
531  s->sa.sin_family = AF_INET;
532  s->sa.sin_addr.s_addr = htonl(s->local ? INADDR_LOOPBACK : INADDR_ANY);
533  s->port = rz_socket_port_by_name(port);
534  if (s->port < 1) {
535  return false;
536  }
537  s->sa.sin_port = htons(s->port); // TODO honor etc/services
538  if (bind(s->fd, (struct sockaddr *)&s->sa, sizeof(s->sa)) < 0) {
539  rz_sys_perror("bind");
540 #ifdef _MSC_VER
541  closesocket(s->fd);
542 #else
543  close(s->fd);
544 #endif
545  return false;
546  }
547 #if __UNIX__
548  rz_sys_signal(SIGPIPE, SIG_IGN);
549 #endif
550  if (s->proto == RZ_SOCKET_PROTO_TCP) {
551  if (listen(s->fd, 32) < 0) {
552  rz_sys_perror("listen");
553 #ifdef _MSC_VER
554  closesocket(s->fd);
555 #else
556  close(s->fd);
557 #endif
558  return false;
559  }
560  }
561 #if HAVE_LIB_SSL
562  if (s->is_ssl) {
563  s->ctx = SSL_CTX_new(SSLv23_method());
564  if (!s->ctx) {
565  rz_socket_free(s);
566  return false;
567  }
568  if (!SSL_CTX_use_certificate_chain_file(s->ctx, certfile)) {
569  rz_socket_free(s);
570  return false;
571  }
572  if (!SSL_CTX_use_PrivateKey_file(s->ctx, certfile, SSL_FILETYPE_PEM)) {
573  rz_socket_free(s);
574  return false;
575  }
576  SSL_CTX_set_verify_depth(s->ctx, 1);
577  }
578 #endif
579  return true;
580 }
int x
Definition: mipsasm.c:20
static struct sockaddr static addrlen listen
Definition: sfsocketcall.h:116
#define SO_LINGER
Definition: sftypes.h:441
#define SO_REUSEADDR
Definition: sftypes.h:430
@ SOCK_DGRAM
Definition: sftypes.h:227
@ SOCK_STREAM
Definition: sftypes.h:224
#define SO_SNDBUF
Definition: sftypes.h:435

References AF_INET, bind, close, eprintf, rz_socket_t::fd, htons, rz_socket_t::is_ssl, listen, rz_socket_t::local, memset(), rz_socket_t::port, rz_socket_t::proto, RZ_INVALID_SOCKET, rz_socket_free(), rz_socket_port_by_name(), RZ_SOCKET_PROTO_DEFAULT, RZ_SOCKET_PROTO_NONE, RZ_SOCKET_PROTO_TCP, RZ_SOCKET_PROTO_UDP, RZ_SOCKET_PROTO_UNIX, rz_sys_perror, rz_sys_signal(), s, in_addr::s_addr, rz_socket_t::sa, sockaddr_in::sin_addr, sockaddr_in::sin_port, SO_LINGER, SO_REUSEADDR, SO_SNDBUF, SOCK_DGRAM, SOCK_STREAM, socket, SOL_SOCKET, and x.

Referenced by __rap_open(), rz_core_rtr_cmds(), rz_core_rtr_gdb_run(), rz_core_rtr_http_run(), rz_main_rz_agent(), rz_run_config_env(), rz_socket_rap_server_listen(), rz_write_from_socket_handler(), and tcpme().

◆ rz_socket_new()

RZ_API RzSocket* rz_socket_new ( bool  is_ssl)

Definition at line 179 of file socket.c.

179  {
181  if (!s) {
182  return NULL;
183  }
184  s->is_ssl = is_ssl;
185  s->port = 0;
186 #if __UNIX_
187  rz_sys_signal(SIGPIPE, SIG_IGN);
188 #endif
189  s->local = 0;
191 #if HAVE_LIB_SSL
192  if (is_ssl) {
193  s->sfd = NULL;
194  s->ctx = NULL;
195  s->bio = NULL;
196 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
197  if (!SSL_library_init()) {
198  rz_socket_free(s);
199  return NULL;
200  }
201  SSL_load_error_strings();
202 #endif
203  }
204 #endif
205  return s;
206 }

References rz_socket_t::fd, rz_socket_t::is_ssl, rz_socket_t::local, NULL, rz_socket_t::port, RZ_INVALID_SOCKET, RZ_NEW0, rz_socket_free(), rz_sys_signal(), and s.

Referenced by __open(), __rap_open(), gdbr_init(), iob_net_open(), qnxr_connect(), rz_core_rtr_add(), rz_core_rtr_cmds(), rz_core_rtr_cmds_query(), rz_core_rtr_gdb_run(), rz_core_rtr_http_run(), rz_core_rtr_http_stop(), rz_main_rz_agent(), rz_run_config_env(), rz_socket_http_post(), rz_socket_rap_server_new(), rz_write_from_socket_handler(), socket_http_get_recursive(), and tcpme().

◆ rz_socket_new_from_fd()

RZ_API RzSocket* rz_socket_new_from_fd ( int  fd)

Definition at line 859 of file socket.c.

859  {
861  if (s) {
862  s->fd = fd;
864  }
865  return s;
866 }
static const z80_opcode fd[]
Definition: z80_tab.h:997

References fd, rz_socket_t::fd, rz_socket_t::proto, RZ_NEW0, RZ_SOCKET_PROTO_DEFAULT, and s.

Referenced by __rap_accept().

◆ rz_socket_port_by_name()

RZ_API int rz_socket_port_by_name ( const char *  name)

Definition at line 469 of file socket.c.

469  {
470  struct servent *p = getservbyname(name, "tcp");
471  return (p && p->s_port) ? ntohs(p->s_port) : rz_num_get(NULL, name);
472 }
void * p
Definition: libc.cpp:67
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
#define ntohs(x)
Definition: sftypes.h:478
Definition: z80asm.h:102

References ntohs, NULL, p, and rz_num_get().

Referenced by rz_socket_connect(), and rz_socket_listen().

◆ rz_socket_printf()

RZ_API void rz_socket_printf ( RzSocket s,
const char *  fmt,
  ... 
)

Definition at line 772 of file socket.c.

772  {
773  char buf[BUFFER_SIZE];
774  va_list ap;
775  if (s->fd != RZ_INVALID_SOCKET) {
776  va_start(ap, fmt);
777  vsnprintf(buf, BUFFER_SIZE, fmt, ap);
778  (void)rz_socket_write(s, buf, strlen(buf));
779  va_end(ap);
780  }
781 }
vsnprintf
Definition: kernel.h:366
#define BUFFER_SIZE
Definition: socket.c:99
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724

References BUFFER_SIZE, rz_socket_t::fd, RZ_INVALID_SOCKET, rz_socket_write(), s, and vsnprintf.

◆ rz_socket_puts()

RZ_API int rz_socket_puts ( RzSocket s,
char *  buf 
)

Definition at line 768 of file socket.c.

768  {
769  return rz_socket_write(s, buf, strlen(buf));
770 }

References rz_socket_write(), and s.

◆ rz_socket_read()

RZ_API int rz_socket_read ( RzSocket s,
unsigned char *  buf,
int  len 
)

Definition at line 783 of file socket.c.

783  {
784  if (!s) {
785  return -1;
786  }
787 #if HAVE_LIB_SSL
788  if (s->is_ssl) {
789  if (s->bio) {
790  return BIO_read(s->bio, buf, len);
791  }
792  return SSL_read(s->sfd, buf, len);
793  }
794 #endif
795  // int r = read (s->fd, buf, len);
796  int r = recv(s->fd, (char *)buf, len, 0);
797  D {
798  eprintf("READ ");
799  int i;
800  for (i = 0; i < len; i++) {
801  eprintf("%02x ", buf[i]);
802  }
803  eprintf("\n");
804  }
805  return r;
806 }
#define D
Definition: socket.c:16

References D, eprintf, rz_socket_t::fd, i, rz_socket_t::is_ssl, len, r, and s.

Referenced by __rap_system(), iob_net_read(), qnxr_read_packet(), read_packet(), runcmd(), rz_core_rtr_cmds(), rz_core_rtr_cmds_query(), rz_socket_gets(), rz_socket_proc_read(), rz_socket_read_block(), rz_socket_slurp(), and rz_write_from_socket_handler().

◆ rz_socket_read_block()

RZ_API int rz_socket_read_block ( RzSocket s,
ut8 buf,
int  len 
)

Definition at line 808 of file socket.c.

808  {
809  int ret = 0;
810  for (ret = 0; ret < len;) {
811  int r = rz_socket_read(s, buf + ret, len - ret);
812  if (r == -1) {
813 #if HAVE_LIB_SSL
814  if (s->is_ssl && SSL_get_error(s->sfd, r) == SSL_ERROR_WANT_READ) {
815  if (rz_socket_ready(s, 1, 0) == 1) {
816  continue;
817  }
818  }
819 #endif
820  return -1;
821  }
822  if (r < 1) {
823  break;
824  }
825  ret += r;
826  }
827  return ret;
828 }

References rz_socket_t::is_ssl, len, r, rz_socket_read(), rz_socket_ready(), and s.

Referenced by __rap_system(), rz_core_rtr_cmd(), rz_core_serve(), rz_socket_http_accept(), rz_socket_rap_client_command(), rz_socket_rap_client_open(), rz_socket_rap_client_read(), rz_socket_rap_client_seek(), rz_socket_rap_client_write(), rz_socket_rap_server_continue(), socket_http_answer(), and socket_slurp().

◆ rz_socket_ready()

RZ_API int rz_socket_ready ( RzSocket s,
int  secs,
int  usecs 
)

Definition at line 688 of file socket.c.

688  {
689  fd_set rfds;
690  struct timeval tv = { secs, usecs };
691  if (s->fd == RZ_INVALID_SOCKET) {
692  return -1;
693  }
694  FD_ZERO(&rfds);
695  FD_SET(s->fd, &rfds);
696  return select(s->fd + 1, &rfds, NULL, NULL, &tv);
697 }

References rz_socket_t::fd, FD_SET, FD_ZERO, NULL, RZ_INVALID_SOCKET, s, select, and tv.

Referenced by qnxr_read_packet(), read_packet(), rz_socket_close(), rz_socket_http_accept(), rz_socket_proc_ready(), rz_socket_read_block(), and socket_slurp().

◆ rz_socket_slurp()

RZ_API ut8* rz_socket_slurp ( RzSocket s,
int len 
)

Definition at line 868 of file socket.c.

868  {
869  int blockSize = 4096;
870  ut8 *ptr, *buf = malloc(blockSize);
871  if (!buf) {
872  return NULL;
873  }
874  int copied = 0;
875  if (len) {
876  *len = 0;
877  }
878  for (;;) {
879  int rc = rz_socket_read(s, buf + copied, blockSize);
880  if (rc > 0) {
881  copied += rc;
882  }
883  ptr = realloc(buf, copied + blockSize);
884  if (!ptr) {
885  break;
886  }
887  buf = ptr;
888  if (rc < 1) {
889  break;
890  }
891  }
892  if (copied == 0) {
893  RZ_FREE(buf);
894  }
895  if (len) {
896  *len = copied;
897  }
898  return buf;
899 }
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
#define RZ_FREE(x)
Definition: rz_types.h:369

References len, malloc(), NULL, realloc(), RZ_FREE, rz_socket_read(), and s.

Referenced by tcpme().

◆ rz_socket_spawn()

RZ_API bool rz_socket_spawn ( RzSocket s,
const char *  cmd,
unsigned int  timeout 
)

Definition at line 208 of file socket.c.

208  {
209  // XXX TODO: dont use sockets, we can achieve the same with pipes
210  const int port = 2000 + rz_num_rand(2000);
211  int childPid = rz_sys_fork();
212  if (childPid == 0) {
213  char *a = rz_str_replace(strdup(cmd), "\\", "\\\\", true);
214  int res = rz_sys_cmdf("rz-run system=\"%s\" listen=%d", a, port);
215  free(a);
216 #if 0
217  // TODO: use the api
218  char *profile = rz_str_newf (
219  "system=%s\n"
220  "listen=%d\n", cmd, port);
221  RzRunProfile *rp = rz_run_new (profile);
222  rz_run_start (rp);
223  rz_run_free (rp);
224  free (profile);
225 #endif
226  if (res != 0) {
227  eprintf("rz_socket_spawn: rz-run failed\n");
228  exit(1);
229  }
230  eprintf("rz_socket_spawn: %s is dead\n", cmd);
231  exit(0);
232  }
233  rz_sys_sleep(1);
235 
236  char aport[32];
237  sprintf(aport, "%d", port);
238  // redirect stdin/stdout/stderr
239  bool sock = rz_socket_connect(s, "127.0.0.1", aport, RZ_SOCKET_PROTO_TCP, 2000);
240  if (!sock) {
241  return false;
242  }
243 #if __UNIX__
244  rz_sys_sleep(4);
246 
247  int status = 0;
248  int ret = waitpid(childPid, &status, WNOHANG);
249  if (ret != 0) {
251  return false;
252  }
253 #endif
254  return true;
255 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
sprintf
Definition: kernel.h:365
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
RZ_API int rz_num_rand(int max)
Definition: unum.c:47
RZ_API void rz_run_free(RzRunProfile *r)
Definition: run.c:122
RZ_API RzRunProfile * rz_run_new(const char *str)
Definition: run.c:86
RZ_API int rz_run_start(RzRunProfile *p)
Definition: run.c:1081
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API int rz_sys_cmdf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API int rz_sys_fork(void)
Definition: sys.c:1679
RZ_API int rz_sys_usleep(int usecs)
Sleep for usecs microseconds.
Definition: sys.c:317
RZ_API int rz_sys_sleep(int secs)
Sleep for secs seconds.
Definition: sys.c:300
#define a(i)
Definition: sha256.c:41
RZ_API bool rz_socket_connect(RzSocket *s, const char *host, const char *port, int proto, unsigned int timeout)
Definition: socket.c:257

References a, cmd, eprintf, test-lz4-list::exit, free(), rp, rz_num_rand(), rz_run_free(), rz_run_new(), rz_run_start(), rz_socket_close(), rz_socket_connect(), RZ_SOCKET_PROTO_TCP, rz_str_newf(), rz_str_replace(), rz_sys_cmdf(), rz_sys_fork(), rz_sys_sleep(), rz_sys_usleep(), s, sprintf, status, strdup(), and timeout.

Referenced by __open().

◆ rz_socket_to_string()

RZ_API char* rz_socket_to_string ( RzSocket s)

Definition at line 699 of file socket.c.

699  {
700 #if __WINDOWS__
701  return rz_str_newf("fd%d", (int)(size_t)s->fd);
702 #elif __UNIX__
703  char *str = NULL;
704  struct sockaddr sa;
705  socklen_t sl = sizeof(sa);
706  memset(&sa, 0, sizeof(sa));
707  if (!getpeername(s->fd, &sa, &sl)) {
708  struct sockaddr_in *sain = (struct sockaddr_in *)&sa;
709  ut8 *a = (ut8 *)&(sain->sin_addr);
710  if ((str = malloc(32))) {
711  sprintf(str, "%d.%d.%d.%d:%d",
712  a[0], a[1], a[2], a[3], ntohs(sain->sin_port));
713  }
714  } else {
715  eprintf("getperrname: failed\n"); // rz_sys_perror ("getpeername");
716  }
717  return str;
718 #else
719  return NULL;
720 #endif
721 }

References a, eprintf, rz_socket_t::fd, malloc(), memset(), ntohs, NULL, rz_str_newf(), s, sockaddr_in::sin_addr, sockaddr_in::sin_port, sprintf, and cmd_descs_generate::str.

Referenced by rz_core_rtr_http_run().

◆ rz_socket_write()

RZ_API int rz_socket_write ( RzSocket s,
void *  buf,
int  len 
)

Definition at line 724 of file socket.c.

724  {
725  D {
726  eprintf("WRITE ");
727  int i;
728  ut8 *b = buf;
729  for (i = 0; i < len; i++) {
730  eprintf("%02x ", b[i]);
731  }
732  eprintf("\n");
733  }
734  int ret, delta = 0;
735 #if __UNIX__
736  rz_sys_signal(SIGPIPE, SIG_IGN);
737 #endif
738  for (;;) {
739  int b = 1500; // 65536; // Use MTU 1500?
740  if (b > len) {
741  b = len;
742  }
743 #if HAVE_LIB_SSL
744  if (s->is_ssl) {
745  if (s->bio) {
746  ret = BIO_write(s->bio, buf + delta, b);
747  } else {
748  ret = SSL_write(s->sfd, buf + delta, b);
749  }
750  } else
751 #endif
752  {
753  ret = send(s->fd, (char *)buf + delta, b, 0);
754  }
755  // if (ret == 0) return -1;
756  if (ret < 1) {
757  break;
758  }
759  if (ret == len) {
760  return len;
761  }
762  delta += ret;
763  len -= ret;
764  }
765  return (ret == -1) ? -1 : delta;
766 }
static struct sockaddr static addrlen static backlog send
Definition: sfsocketcall.h:119
#define b(i)
Definition: sha256.c:42
static st64 delta
Definition: vmenus.c:2425

References b, D, delta, eprintf, rz_socket_t::fd, i, rz_socket_t::is_ssl, len, rz_sys_signal(), s, and send.

Referenced by __rap_system(), _sendResponsePacket(), iob_net_write(), qnxr_send_ch_debug(), qnxr_send_ch_reset(), qnxr_send_ch_text(), qnxr_send_nak(), qnxr_send_packet(), rz_core_rtr_cmd(), rz_core_rtr_cmds(), rz_core_rtr_cmds_query(), rz_core_rtr_pushout(), rz_core_serve(), rz_socket_http_post(), rz_socket_http_response(), rz_socket_printf(), rz_socket_proc_printf(), rz_socket_proc_write(), rz_socket_puts(), rz_socket_rap_client_command(), rz_socket_rap_client_open(), rz_socket_rap_client_read(), rz_socket_rap_client_seek(), rz_socket_rap_client_write(), rz_socket_rap_server_continue(), send_ack(), send_packet(), and send_vcont().