Rizin
unix-like reverse engineering framework and cli tools
socket.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2006-2021 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /* must be included first because of winsock2.h and windows.h */
5 #include <rz_socket.h>
6 #include <rz_types.h>
7 #include <rz_util.h>
8 #include <errno.h>
9 
10 #if EMSCRIPTEN
11 #define NETWORK_DISABLED 1
12 #else
13 #define NETWORK_DISABLED 0
14 #endif
15 
16 #define D if (0)
17 
18 RZ_LIB_VERSION(rz_socket);
19 
20 #if NETWORK_DISABLED
21 /* no network */
22 RZ_API RzSocket *rz_socket_new(bool is_ssl) {
23  return NULL;
24 }
26  return false;
27 }
28 RZ_API bool rz_socket_connect(RzSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
29  return false;
30 }
31 RZ_API bool rz_socket_spawn(RzSocket *s, const char *cmd, unsigned int timeout) {
32  return -1;
33 }
35  return -1;
36 }
38  return -1;
39 }
41  return -1;
42 }
43 RZ_API int rz_socket_port_by_name(const char *name) {
44  return -1;
45 }
46 RZ_API bool rz_socket_listen(RzSocket *s, const char *port, const char *certfile) {
47  return false;
48 }
50  return NULL;
51 }
53  return NULL;
54 }
55 RZ_API bool rz_socket_block_time(RzSocket *s, bool block, int sec, int usec) {
56  return false;
57 }
59  return -1;
60 }
61 RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs) {
62  return -1;
63 }
65  return NULL;
66 }
67 RZ_API int rz_socket_write(RzSocket *s, void *buf, int len) {
68  return -1;
69 }
70 RZ_API int rz_socket_puts(RzSocket *s, char *buf) {
71  return -1;
72 }
73 RZ_API void rz_socket_printf(RzSocket *s, const char *fmt, ...) {
74  /* nothing here */
75 }
76 RZ_API int rz_socket_read(RzSocket *s, unsigned char *buf, int len) {
77  return -1;
78 }
79 RZ_API int rz_socket_read_block(RzSocket *s, unsigned char *buf, int len) {
80  return -1;
81 }
82 RZ_API int rz_socket_gets(RzSocket *s, char *buf, int size) {
83  return -1;
84 }
86  return NULL;
87 }
89  return NULL;
90 }
91 #else
92 
93 #if 0
94 winsock api notes
95 =================
96 close: closes the socket without flushing the data
97 WSACleanup: closes all network connections
98 #endif
99 #define BUFFER_SIZE 4096
100 
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 }
123 
124 #if __UNIX__
125 static bool __connect_unix(RzSocket *s, const char *file) {
126  struct sockaddr_un addr;
127  int sock = socket(PF_UNIX, SOCK_STREAM, 0);
128  if (sock < 0) {
129  free(s);
130  return false;
131  }
132  // TODO: set socket options
133  addr.sun_family = AF_UNIX;
134  strncpy(addr.sun_path, file, sizeof(addr.sun_path) - 1);
135 
136  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
137  close(sock);
138  free(s);
139  return false;
140  }
141  s->fd = sock;
142  s->is_ssl = false;
143  return true;
144 }
145 
146 static bool __listen_unix(RzSocket *s, const char *file) {
147  struct sockaddr_un unix_name;
148  int sock = socket(PF_UNIX, SOCK_STREAM, 0);
149  if (sock < 0) {
150  return false;
151  }
152  // TODO: set socket options
153  unix_name.sun_family = AF_UNIX;
154  strncpy(unix_name.sun_path, file, sizeof(unix_name.sun_path) - 1);
155 
156  /* just to make sure there is no other socket file */
157  unlink(unix_name.sun_path);
158 
159  if (bind(sock, (struct sockaddr *)&unix_name, sizeof(unix_name)) < 0) {
160  close(sock);
161  return false;
162  }
163  rz_sys_signal(SIGPIPE, SIG_IGN);
164 
165  /* change permissions */
166  if (chmod(unix_name.sun_path, 0777) != 0) {
167  close(sock);
168  return false;
169  }
170  if (listen(sock, 1)) {
171  close(sock);
172  return false;
173  }
174  s->fd = sock;
175  return true;
176 }
177 #endif
178 
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 }
207 
208 RZ_API bool rz_socket_spawn(RzSocket *s, const char *cmd, unsigned int timeout) {
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 }
256 
257 RZ_API bool rz_socket_connect(RzSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
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 }
408 
409 /* close the file descriptor associated with the RzSocket s */
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 }
417 
418 /* shutdown the socket and close the file descriptor */
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 }
451 
452 /* shutdown the socket, close the file descriptor and free the RzSocket */
454  int res = rz_socket_close(s);
455 #if HAVE_LIB_SSL
456  if (s && s->is_ssl) {
457  if (s->sfd) {
458  SSL_free(s->sfd);
459  }
460  if (s->ctx) {
461  SSL_CTX_free(s->ctx);
462  }
463  }
464 #endif
465  free(s);
466  return res;
467 }
468 
470  struct servent *p = getservbyname(name, "tcp");
471  return (p && p->s_port) ? ntohs(p->s_port) : rz_num_get(NULL, name);
472 }
473 
474 RZ_API bool rz_socket_listen(RzSocket *s, const char *port, const char *certfile) {
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 }
581 
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 }
625 
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 }
647 
648 // Only applies to read in UNIX
649 RZ_API bool rz_socket_block_time(RzSocket *s, bool block, int sec, int usec) {
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 }
676 
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 }
685 
686 /* waits secs until new data is received. */
687 /* returns -1 on error, 0 is false, 1 is true */
688 RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs) {
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 }
698 
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 }
722 
723 /* Read/Write functions */
724 RZ_API int rz_socket_write(RzSocket *s, void *buf, int len) {
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 }
767 
769  return rz_socket_write(s, buf, strlen(buf));
770 }
771 
772 RZ_API void rz_socket_printf(RzSocket *s, const char *fmt, ...) {
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 }
782 
783 RZ_API int rz_socket_read(RzSocket *s, unsigned char *buf, int len) {
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 }
807 
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 }
829 
830 RZ_API int rz_socket_gets(RzSocket *s, char *buf, int size) {
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 }
858 
861  if (s) {
862  s->fd = fd;
864  }
865  return s;
866 }
867 
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 }
900 
901 #endif // EMSCRIPTEN
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
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 fork const void static count close
Definition: sflib.h:33
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 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
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 static fork const void static count static fd const char const char static newpath const char static path chmod
Definition: sflib.h:35
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static char * rp[]
Definition: i8080dis.c:36
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
sprintf
Definition: kernel.h:365
vsnprintf
Definition: kernel.h:366
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
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
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 static fork const void static count static fd const char static mode unlink
Definition: sflib.h:41
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
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
int x
Definition: mipsasm.c:20
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API int rz_num_rand(int max)
Definition: unum.c:47
#define RZ_SOCKET_PROTO_NONE
Definition: rz_socket.h:90
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
#define RZ_SOCKET_PROTO_UNIX
Definition: rz_socket.h:89
#define SD_SEND
Definition: rz_socket.h:41
#define RZ_SOCKET_PROTO_UDP
Definition: rz_socket.h:88
RZ_API int rz_run_start(RzRunProfile *p)
Definition: run.c:1081
#define RZ_SOCKET_PROTO_TCP
Definition: rz_socket.h:87
#define RZ_INVALID_SOCKET
Definition: rz_socket.h:48
#define RZ_SOCKET_PROTO_DEFAULT
Definition: rz_socket.h:91
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_signal(int sig, void(*handler)(int))
Definition: sys.c:178
RZ_API int rz_sys_sleep(int secs)
Sleep for secs seconds.
Definition: sys.c:300
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
static struct sockaddr static addrlen static backlog send
Definition: sfsocketcall.h:119
static struct sockaddr static addrlen listen
Definition: sfsocketcall.h:116
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static bind
Definition: sfsocketcall.h:114
#define F_GETFL
Definition: sftypes.h:506
#define PF_UNIX
Definition: sftypes.h:246
#define SO_ERROR
Definition: sftypes.h:432
#define AF_UNIX
Definition: sftypes.h:285
#define FD_ZERO(set)
Definition: sftypes.h:204
#define FD_ISSET(d, set)
Definition: sftypes.h:214
#define O_NONBLOCK
Definition: sftypes.h:494
#define FD_SET(d, set)
Definition: sftypes.h:212
#define htons(x)
Definition: sftypes.h:475
#define SO_LINGER
Definition: sftypes.h:441
#define SO_REUSEADDR
Definition: sftypes.h:430
#define EINPROGRESS
Definition: sftypes.h:175
unsigned int socklen_t
Definition: sftypes.h:219
@ SOCK_DGRAM
Definition: sftypes.h:227
@ SOCK_STREAM
Definition: sftypes.h:224
#define SOL_SOCKET
Definition: sftypes.h:427
#define AF_INET
Definition: sftypes.h:287
#define ntohs(x)
Definition: sftypes.h:478
#define AF_UNSPEC
Definition: sftypes.h:283
#define F_SETFL
Definition: sftypes.h:507
#define SO_RCVTIMEO
Definition: sftypes.h:448
#define FIONBIO
Definition: sftypes.h:736
#define SO_SNDBUF
Definition: sftypes.h:435
int ssize_t
Definition: sftypes.h:39
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
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_read_block(RzSocket *s, ut8 *buf, int len)
Definition: socket.c:808
RZ_API int rz_socket_puts(RzSocket *s, char *buf)
Definition: socket.c:768
RZ_API int rz_socket_read(RzSocket *s, unsigned char *buf, int len)
Definition: socket.c:783
RZ_API int rz_socket_close_fd(RzSocket *s)
Definition: socket.c:410
RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs)
Definition: socket.c:688
RZ_API int rz_socket_port_by_name(const char *name)
Definition: socket.c:469
RZ_API RzSocket * rz_socket_accept(RzSocket *s)
Definition: socket.c:582
RZ_API bool rz_socket_spawn(RzSocket *s, const char *cmd, unsigned int timeout)
Definition: socket.c:208
#define BUFFER_SIZE
Definition: socket.c:99
RZ_API bool rz_socket_listen(RzSocket *s, const char *port, const char *certfile)
Definition: socket.c:474
RZ_API int rz_socket_flush(RzSocket *s)
Definition: socket.c:677
RZ_API bool rz_socket_block_time(RzSocket *s, bool block, int sec, int usec)
Definition: socket.c:649
RZ_API char * rz_socket_to_string(RzSocket *s)
Definition: socket.c:699
RZ_API int rz_socket_gets(RzSocket *s, char *buf, int size)
Definition: socket.c:830
RZ_API bool rz_socket_connect(RzSocket *s, const char *host, const char *port, int proto, unsigned int timeout)
Definition: socket.c:257
RZ_API RzSocket * rz_socket_accept_timeout(RzSocket *s, unsigned int timeout)
Definition: socket.c:626
RZ_LIB_VERSION(rz_socket)
RZ_API RzSocket * rz_socket_new(bool is_ssl)
Definition: socket.c:179
RZ_API ut8 * rz_socket_slurp(RzSocket *s, int *len)
Definition: socket.c:868
RZ_API void rz_socket_printf(RzSocket *s, const char *fmt,...)
Definition: socket.c:772
RZ_API RzSocket * rz_socket_new_from_fd(int fd)
Definition: socket.c:859
RZ_API int rz_socket_free(RzSocket *s)
Definition: socket.c:453
#define D
Definition: socket.c:16
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724
Definition: gzappend.c:170
in_addr_t s_addr
Definition: sftypes.h:337
Definition: z80asm.h:102
bool is_ssl
Definition: rz_socket.h:68
struct sockaddr_in sa
Definition: rz_socket.h:72
struct in_addr sin_addr
Definition: sftypes.h:344
in_port_t sin_port
Definition: sftypes.h:343
uv_timer_t timeout
Definition: main.c:9
void error(const char *msg)
Definition: untgz.c:593
static st64 delta
Definition: vmenus.c:2425
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int addr
Definition: z80asm.c:58
#define FAR
Definition: zconf.h:387