R_API int r_socket_connect (RSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
#if __WINDOWS__ && !defined(__CYGWIN__) && !defined(__MINGW64__)
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
	if (s->fd == -1)
		return false;

	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
		close (s->fd);
		return false;
	}

	sa.sin_addr = *((struct in_addr *)he->h_addr);

	s->port = r_socket_port_by_name (port);
	sa.sin_port = htons (s->port);
#warning TODO: implement connect timeout on w32
	if (connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
		close (s->fd);
		return false;
	}
	return true;
#elif __UNIX__ || defined(__CYGWIN__)
	int gai, ret;
	struct addrinfo hints, *res, *rp;
	if (!proto) proto = R_SOCKET_PROTO_TCP;
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host))
			return false;
	} else {
		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			//eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return false;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			int flag = 1;

			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1)
				continue;

			ret = setsockopt (s->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
			if (ret < 0) {
				close (s->fd);
				s->fd = -1;
				continue;
			}

			if (timeout>0) {
				r_socket_block_time (s, 1, timeout);
				//fcntl (s->fd, F_SETFL, O_NONBLOCK, 1);
			}
			ret = connect (s->fd, rp->ai_addr, rp->ai_addrlen);

			if (timeout == 0 && ret == 0) {
				freeaddrinfo (res);
				return true;

			} else if (ret == 0 /* || nonblocking */) {

				struct timeval tv;
				fd_set fdset, errset;
				FD_ZERO (&fdset);
				FD_SET (s->fd, &fdset);
				tv.tv_sec = 1; //timeout;
				tv.tv_usec = 0;

				if (r_socket_is_connected (s)) {
					freeaddrinfo (res);
					return true;
				}
				if (select (s->fd + 1, NULL, NULL, &errset, &tv) == 1) {
					int so_error;
					socklen_t len = sizeof so_error;
					ret = getsockopt (s->fd, SOL_SOCKET,
						SO_ERROR, &so_error, &len);

					if (ret == 0 && so_error == 0) {
						//fcntl (s->fd, F_SETFL, O_NONBLOCK, 0);
						//r_socket_block_time (s, 0, 0);
						freeaddrinfo (res);
						return true;
					}
				}
			}
			close (s->fd);
			s->fd = -1;
		}
		freeaddrinfo (res);
		if (rp == NULL) {
			eprintf ("Could not resolve address '%s'\n", host);
			return false;
		}
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (s->ctx == NULL) {
			r_socket_free (s);
			return false;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return false;
		}
	}
#endif
	return true;
}
Beispiel #2
0
int send_vcont(libgdbr_t *g, const char *command, const char *thread_id) {
	char tmp[255] = {0};
	int ret;
	if (!g) {
		return -1;
	}
	if (!g->stub_features.vContSupported) {
		ret = snprintf (tmp, sizeof (tmp) - 1, "%s", command);
	} else {
		bool supported = false;
		switch (*command) {
		case 's':
			if (g->stub_features.vcont.s) {
				supported = true;
			}
			break;
		case 'S':
			if (g->stub_features.vcont.S) {
				supported = true;
			}
			break;
		case 'c':
			if (g->stub_features.vcont.c) {
				supported = true;
			}
			break;
		case 'C':
			if (g->stub_features.vcont.C) {
				supported = true;
			}
			break;
		case 't':
			if (g->stub_features.vcont.t) {
				supported = true;
			}
			break;
		case 'r':
			if (g->stub_features.vcont.r) {
				supported = true;
			}
			break;
		}
		if (supported) {
			if (!thread_id) {
				ret = snprintf (tmp, sizeof (tmp) - 1, "%s;%s", CMD_C, command);
			} else {
				ret = snprintf (tmp, sizeof (tmp) - 1, "%s;%s:%s", CMD_C, command, thread_id);
			}
		} else {
			ret = snprintf (tmp, sizeof (tmp) - 1, "%s", command);
		}
	}
	if (ret < 0) {
		return ret;
	}
	reg_cache.valid = false;
	g->stop_reason.is_valid = false;
	ret = send_msg (g, tmp);
	if (ret < 0) {
		return ret;
	}

	SET_SIGINT_HANDLER (g, _sigint_handler);
	while ((ret = read_packet (g, true)) < 0 && !_isbreaked && r_socket_is_connected (g->sock));
	UNSET_SIGINT_HANDLER ();
	if (_isbreaked) {
		_isbreaked = false;
		// Stop target
		r_socket_write (g->sock, "\x03", 1);
		// Read the stop reason
		if (read_packet (g, false) < 0) {
			return -1;
		}
	}
	return handle_cont (g);
}
Beispiel #3
0
R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
#if __WINDOWS__
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	TIMEVAL Timeout;
	Timeout.tv_sec = timeout;
	Timeout.tv_usec = 0;

	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
#ifdef _MSC_VER
	if (s->fd == INVALID_SOCKET) {
#else
	if (s->fd == -1) {
#endif
		return false;
	}

	unsigned long iMode = 1;
	int iResult = ioctlsocket (s->fd, FIONBIO, &iMode);
	if (iResult != NO_ERROR) {
		eprintf ("ioctlsocket error: %d\n", iResult);
	}
	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
#ifdef _MSC_VER
		closesocket (s->fd);
#else
		close (s->fd);
#endif
		return false;
	}
	sa.sin_addr = *((struct in_addr *)he->h_addr);
	s->port = r_socket_port_by_name (port);
	sa.sin_port = htons (s->port);
	if (!connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
#ifdef _MSC_VER
		closesocket (s->fd);
#else
		close (s->fd);
#endif
		return false;
	}
	iMode = 0;
	iResult = ioctlsocket (s->fd, FIONBIO, &iMode);
	if (iResult != NO_ERROR) {
		eprintf ("ioctlsocket error: %d\n", iResult);
	}
	if (timeout > 0) {
		r_socket_block_time (s, 1, timeout);
	}
	fd_set Write, Err;
	FD_ZERO (&Write);
	FD_ZERO (&Err);
	FD_SET (s->fd, &Write);
	FD_SET (s->fd, &Err);
	select (0, NULL, &Write, &Err, &Timeout);
	if (FD_ISSET (s->fd, &Write)) {
		return true;
	}
	return false;
#elif __UNIX__
	int ret;
	struct addrinfo hints = {0};
	struct addrinfo *res, *rp;
	if (!proto) {
		proto = R_SOCKET_PROTO_TCP;
	}
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host)) {
			return false;
		}
	} else {
		hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		int gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return false;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			int flag = 1;

			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1) {
				perror ("socket");
				continue;
			}
			ret = setsockopt (s->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof (flag));
			if (ret < 0) {
				perror ("setsockopt");
				close (s->fd);
				s->fd = -1;
				continue;
			}
			if (timeout > 0) {
				r_socket_block_time (s, 1, timeout);
				//fcntl (s->fd, F_SETFL, O_NONBLOCK, 1);
			}
			ret = connect (s->fd, rp->ai_addr, rp->ai_addrlen);

			if (timeout == 0 && ret == 0) {
				freeaddrinfo (res);
				return true;
			}
			if (ret == 0 /* || nonblocking */) {
				struct timeval tv;
				fd_set fdset, errset;
				FD_ZERO (&fdset);
				FD_SET (s->fd, &fdset);
				tv.tv_sec = 1; //timeout;
				tv.tv_usec = 0;

				if (r_socket_is_connected (s)) {
					freeaddrinfo (res);
					return true;
				}
				if (select (s->fd + 1, NULL, NULL, &errset, &tv) == 1) {
					int so_error;
					socklen_t len = sizeof so_error;
					ret = getsockopt (s->fd, SOL_SOCKET,
						SO_ERROR, &so_error, &len);

					if (ret == 0 && so_error == 0) {
						//fcntl (s->fd, F_SETFL, O_NONBLOCK, 0);
						//r_socket_block_time (s, 0, 0);
						freeaddrinfo (res);
						return true;
					}
				}
			}
			close (s->fd);
			s->fd = -1;
		}
		freeaddrinfo (res);
		if (!rp) {
			eprintf ("Could not resolve address '%s' or failed to connect\n", host);
			return false;
		}
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (!s->ctx) {
			r_socket_free (s);
			return false;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return false;
		}
	}
#endif
	return true;
}

/* close the file descriptor associated with the RSocket s */
R_API int r_socket_close_fd(RSocket *s) {
#ifdef _MSC_VER
	return s->fd != INVALID_SOCKET ? closesocket (s->fd) : false;
#else
	return s->fd != -1 ? close (s->fd) : false;
#endif
}

/* shutdown the socket and close the file descriptor */
R_API int r_socket_close(RSocket *s) {
	int ret = false;
	if (!s) {
		return false;
	}
	if (s->fd != -1) {
#if __UNIX__
		shutdown (s->fd, SHUT_RDWR);
#endif
#if __WINDOWS__
		// https://msdn.microsoft.com/en-us/library/windows/desktop/ms740481(v=vs.85).aspx
		shutdown (s->fd, SD_SEND);
		if (r_socket_ready (s, 0, 250)) {
			do {
				char buf = 0;
				ret = recv (s->fd, &buf, 1, 0);
			} while (ret != 0 && ret != SOCKET_ERROR);
		}
		ret = closesocket (s->fd);
#else
		ret = close (s->fd);
#endif
	}
#if HAVE_LIB_SSL
	if (s->is_ssl && s->sfd) {
		SSL_free (s->sfd);
		s->sfd = NULL;
	}
#endif
	return ret;
}
Beispiel #4
0
R_API int r_socket_rap_server_continue (RSocketRapServer *rap_s)
{
	int endian, i, pipe_fd, ret;
	ut64 offset;
	char *ptr = NULL;
	if (	!rap_s || !rap_s->fd || !r_socket_is_connected (rap_s->fd))
		return R_FALSE;
	r_socket_read_block (rap_s->fd, rap_s->buf, 1);
	endian = getEndian();
	ret = rap_s->buf[0];
	switch (rap_s->buf[0]) {
		case RAP_RMT_OPEN:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2);
			r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]);
			rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0);
			rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_READ:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian);
			if (i > RAP_RMT_MAX || i < 0)
				i = RAP_RMT_MAX;
			rap_s->read (rap_s->user, &rap_s->buf[5], i);
			rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, i + 5);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_WRITE:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian);
			if (i > RAP_RMT_MAX || i < 0)
				i = RAP_RMT_MAX;
			r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
			rap_s->write(rap_s->user, &rap_s->buf[5], i);
			rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 1);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_SEEK:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9);
			i = rap_s->buf[1];
			r_mem_copyendian ((ut8*)&offset, &rap_s->buf[2], 8, !endian);
			rap_s->seek (rap_s->user, offset, i);
			rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 1);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_SYSTEM:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian);
			r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
			ptr = rap_s->system (rap_s->user, &rap_s->buf[5]);
			if (ptr)
				i = strlen (ptr) + 1;
			else	i = 0;
			r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian);
			rap_s->buf[0] = RAP_RMT_SYSTEM | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			if (i)	r_socket_write (rap_s->fd, ptr, i);
			r_socket_flush (rap_s->fd);
			free (ptr);
			ptr = NULL;
			break;
		case RAP_RMT_CMD:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian);
			r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
			ptr = rap_s->cmd (rap_s->user, &rap_s->buf[5]);
			if (ptr)
				i = strlen (ptr) + 1;
			else	i = 0;
			r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian);
			rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			if (i)	r_socket_write (rap_s->fd, ptr, i);
			r_socket_flush (rap_s->fd);
			free (ptr);
			ptr = NULL;
			break;
		case RAP_RMT_CLOSE:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian);
			rap_s->close (rap_s->user, i);
			rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			r_socket_flush (rap_s->fd);
			break;
		default:
			eprintf ("unknown command 0x%02hhx\n", rap_s->buf[0]);
			r_socket_close (rap_s->fd);
			ret = -1;
			break;
	}
	return ret;
}
Beispiel #5
0
R_API bool r_socket_rap_server_continue (RSocketRapServer *rap_s) {
	int i, whence, ret = true;
	ut64 offset;
	char *ptr = NULL;
	if (!rap_s || !rap_s->fd)
		return false;
	if (!r_socket_is_connected (rap_s->fd))
		return false;
	r_socket_read_block (rap_s->fd, rap_s->buf, 1);
	ret = rap_s->buf[0];
	switch (ret) {
	case RAP_RMT_OPEN:
		r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2);
		r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]);
		rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0);
		rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY;
		r_socket_write (rap_s->fd, rap_s->buf, 5);
		r_socket_flush (rap_s->fd);
		break;
	case RAP_RMT_READ:
		r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
		i = r_read_be32 (&rap_s->buf[1]);
		if (i > RAP_RMT_MAX || i < 0)
			i = RAP_RMT_MAX;
		rap_s->read (rap_s->user, &rap_s->buf[5], i);
		rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY;
		r_socket_write (rap_s->fd, rap_s->buf, i + 5);
		r_socket_flush (rap_s->fd);
		break;
	case RAP_RMT_WRITE:
		r_socket_read_block (rap_s->fd, rap_s->buf + 1, 4);
		i = r_read_be32 (rap_s->buf + 1);
		if (i > RAP_RMT_MAX || i < 0) {
			i = RAP_RMT_MAX;
		}
		r_socket_read_block (rap_s->fd, rap_s->buf + 5, i);
		int ret = rap_s->write (rap_s->user, rap_s->buf + 5, i);
		r_write_be32 (rap_s->buf + 1, ret);
		rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY;
		r_socket_write (rap_s->fd, rap_s->buf, 5);
		r_socket_flush (rap_s->fd);
		break;
	case RAP_RMT_SEEK:
		r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9);
		whence = rap_s->buf[1];
		offset = r_read_be64 (rap_s->buf + 2);
		offset = rap_s->seek (rap_s->user, offset, whence);
		/* prepare reply */
		rap_s->buf[0] = RAP_RMT_SEEK | RAP_RMT_REPLY;
		r_write_be64 (rap_s->buf + 1, offset);
		r_socket_write (rap_s->fd, rap_s->buf, 9);
		r_socket_flush (rap_s->fd);
		break;
	case RAP_RMT_CMD:
		r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
		i = r_read_be32 (&rap_s->buf[1]);
		r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
		ptr = rap_s->cmd (rap_s->user, (const char *)&rap_s->buf[5]);
		i = (ptr)? strlen (ptr) + 1: 0;
		r_write_be32 (&rap_s->buf[1], i);
		rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY;
		r_socket_write (rap_s->fd, rap_s->buf, 5);
		if (i)	r_socket_write (rap_s->fd, ptr, i);
		r_socket_flush (rap_s->fd);
		free (ptr);
		ptr = NULL;
		break;
	case RAP_RMT_CLOSE:
		r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
		i = r_read_be32 (&rap_s->buf[1]);
		rap_s->close (rap_s->user, i);
		rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY;
		r_socket_write (rap_s->fd, rap_s->buf, 5);
		r_socket_flush (rap_s->fd);
		break;
	default:
		eprintf ("unknown command 0x%02x\n", \
			(unsigned int)(unsigned char)rap_s->buf[0]);
		r_socket_close (rap_s->fd);
		ret = false;
		break;
	}
	return ret;
}