Exemplo n.º 1
0
bool create_notification_pipe(LIBEVENT_THREAD *me)
{
    int j;
    if (evutil_socketpair(SOCKETPAIR_AF, SOCK_STREAM, 0,
                          (void*)me->notify) == SOCKET_ERROR) {
        log_socket_error(EXTENSION_LOG_WARNING, NULL,
                         "Can't create notify pipe: %s");
        return false;
    }

    for (j = 0; j < 2; ++j) {
        int flags = 1;
        setsockopt(me->notify[j], IPPROTO_TCP,
                   TCP_NODELAY, (void *)&flags, sizeof(flags));
        setsockopt(me->notify[j], SOL_SOCKET,
                   SO_REUSEADDR, (void *)&flags, sizeof(flags));


        if (evutil_make_socket_nonblocking(me->notify[j]) == -1) {
            log_socket_error(EXTENSION_LOG_WARNING, NULL,
                             "Failed to enable non-blocking: %s");
            return false;
        }
    }
    return true;
}
Exemplo n.º 2
0
/* Non-blocking poll. Enter the debugger loop if a message is received. */
void gdbstub_recv(void) {
	int ret, on;
	if (!socket_fd) {
		ret = accept(listen_socket_fd, NULL, NULL);
		if (ret == -1)
			return;
		socket_fd = ret;
		/* Disable Nagle for low latency */
		on = 1;
#ifdef __MINGW32__
		ret = setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&on, sizeof(on));
#else
		ret = setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
#endif
		if (ret == -1)
			log_socket_error("setsockopt(TCP_NODELAY) failed for GDB stub socket");
		
		/* Interface with Ndless */
		if (ndls_is_installed())
			armloader_load_snippet(SNIPPET_ndls_debug_alloc, NULL, 0, gdb_connect_ndls_cb);
		gdb_connected = true;
		puts("GDB connected.");
		return;
	}
	fd_set rfds;
	FD_ZERO(&rfds);
	FD_SET((unsigned)socket_fd, &rfds);
	ret = select(socket_fd + 1, &rfds, NULL, NULL, &(struct timeval) {0, 0});
Exemplo n.º 3
0
/* Read exactly n bytes from the DAC connection socket.
 *
 * This reads exactly len bytes into buf. Data is read in chunks from the
 * OS socket library and buffered in the dac_conn_t structure; individual
 * sections are then copied out.
 *
 * Returns 0 on success, -1 on error. If an error occurs, this will call
 * log_socket_error() to log the issue. The error code is also available
 * from WSAGetLastError().
 */ 
int dac_read_bytes(dac_t *d, char *buf, int len) {
	while (d->conn.size < len) {
		// Wait for readability.
		int res = wait_for_activity(d, DEFAULT_TIMEOUT);

		if (res < 0) {
			closesocket(d->conn.sock);
			d->conn.sock = INVALID_SOCKET;
			return -1;
		} else if (res == 0) {
			flogd(d, "!! Read from DAC timed out.\n");
			closesocket(d->conn.sock);
			d->conn.sock = INVALID_SOCKET;
			return -1;
		}

		res = recv(d->conn.sock, d->conn.buf + d->conn.size,
			len - d->conn.size, 0);

		if (res == 0 || res == SOCKET_ERROR) {
			log_socket_error(d, "recv");
			return -1;
		}

		d->conn.size += res;
	}

	memcpy(buf, d->conn.buf, len);
	if (d->conn.size > len) {
		memmove(d->conn.buf, d->conn.buf + len, d->conn.size - len);
	}
	d->conn.size -= len;

	return 0;
}
Exemplo n.º 4
0
static void drain_notification_channel(evutil_socket_t fd)
{
    int nread;
    while ((nread = recv(fd, devnull, sizeof(devnull), 0)) == (int)sizeof(devnull)) {
        /* empty */
    }

    if (nread == -1) {
        log_socket_error(EXTENSION_LOG_WARNING, NULL,
                         "Can't read from libevent pipe: %s");
    }
}
Exemplo n.º 5
0
static void gdbstub_bind(int port) {
	struct sockaddr_in sockaddr;
	int r;
	
#ifdef __MINGW32__
	WORD wVersionRequested = MAKEWORD(2, 0);
	WSADATA wsaData;
	if (WSAStartup(wVersionRequested, &wsaData)) {
		log_socket_error("WSAStartup failed");
		exit(1);
	}
#endif

	listen_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
	if (listen_socket_fd == -1) {
		log_socket_error("Failed to create GDB stub socket");
		exit(1);
	}
#ifdef __MINGW32__
	u_long mode = 1;
	ioctlsocket(listen_socket_fd, FIONBIO, &mode);
#else
  ret = fcntl(listen_socket_fd, F_GETFL, 0);
  fcntl(listen_socket_fd, F_SETFL, ret | O_NONBLOCK);
#endif

	memset (&sockaddr, '\000', sizeof sockaddr);
	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(port);
	sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	r = bind(listen_socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
	if (r == -1) {
		log_socket_error("Failed to bind GDB stub socket. Check that nspire_emu is not already running");
		exit(1);
	}
	r = listen(listen_socket_fd, 0);
	if (r == -1) {
		log_socket_error("Failed to listen on GDB stub socket");
	}
}
Exemplo n.º 6
0
int tcp_connect(const char *host, int port)
{
    SOCKET sockfd;
    struct sockaddr_in servaddr;
    char ipbuf[16];

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        log_socket_error(L_ERROR|L_CONS, "[tcp_connect] "
                         "socket() failed for %s, %d",
                         host, port);
        return -1;
    }

    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    servaddr.sin_addr.s_addr = ip_getaddr(host);

    if(servaddr.sin_addr.s_addr == htonl(INADDR_NONE)) {
        radlog(L_ERROR|L_CONS, "[tcp_connect] "
               "invalid host %s", host);
        closesocket(sockfd);
        return -1;
    }

    if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) == SOCKET_ERROR) {
        log_socket_error(L_ERROR|L_CONS, "[tcp_connect] "
                         "connect() failed for %s (%s), %d",
                         host, ip_ntoa(ipbuf, servaddr.sin_addr.s_addr), port);
        closesocket(sockfd);
        return -1;
    }

    DEBUG("[tcp_connect] %s (%s:%d), got sockfd(%d)", host,
          ip_ntoa(ipbuf, servaddr.sin_addr.s_addr), port, sockfd);

    return sockfd;
}
Exemplo n.º 7
0
/* Wait for writability.
 */
int wait_for_write(dac_t *d, int usec) {
	fd_set set;
	FD_ZERO(&set);
	FD_SET(d->conn.sock, &set);
	struct timeval time;
	time.tv_sec = usec / 1000000;
	time.tv_usec = usec % 1000000;
	int res = select(0, NULL, &set, &set, &time);

	if (res == SOCKET_ERROR) {
		log_socket_error(d, "select");
		return -1;
	}

	return res;
}
Exemplo n.º 8
0
static void flush_out_buffer(void) {
	char *p = sockbuf;
	while (p != sockbufptr) {
		int n = send(socket_fd, p, sockbufptr-p, 0);
		if (n == -1) {
#ifdef __MINGW32__
			if (WSAGetLastError() == WSAEWOULDBLOCK)
#else
			if (errno == EAGAIN)
#endif
				continue; // not ready to send
			else {
				log_socket_error("Failed to send to GDB stub socket");
				break;
			}
		}
		p += n;
	}
	sockbufptr = sockbuf;
}
Exemplo n.º 9
0
int dac_sendall(dac_t *d, const char *data, int len) {
	do {
		int res = wait_for_write(d, 1500000);
		if (res < 0) {
			return -1;
		} else if (res == 0) {
			trace(d, "write timed out\n");
		}

		res = send(d->conn.sock, data, len, 0);

		if (res == SOCKET_ERROR) {
			log_socket_error(d, "send");
			return -1;
		}

		len -= res;
		data += res;
	} while (len);

	return 0;
}
Exemplo n.º 10
0
/* Initialize a dac_conn_t and connect to the DAC.
 *
 * On success, return 0.
 */
int dac_connect(dac_t *d, const char *host, const char *port) {
	dac_conn_t *conn = &d->conn;
	ZeroMemory(conn, sizeof(d->conn));

	// Look up the server address
	struct addrinfo *result = NULL, *ptr = NULL, hints;
	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	trace(d, "Calling getaddrinfo: \"%s\", \"%s\"\n", host, port);

	int res = getaddrinfo(host, port, &hints, &result);
	if (res != 0) {
		trace(d, "getaddrinfo failed: %d\n", res);
		return -1;
	}

	// Create a SOCKET
	ptr = result;
	conn->sock = socket(ptr->ai_family, ptr->ai_socktype, 
		ptr->ai_protocol);

	if (conn->sock == INVALID_SOCKET) {
		log_socket_error(d, "socket");
		freeaddrinfo(result);
		return -1;
	}

	unsigned long nonblocking = 1;
	ioctlsocket(conn->sock, FIONBIO, &nonblocking);

	memset(&conn->udp_target, 0, sizeof(conn->udp_target));
	conn->udp_target.sin_family = AF_INET;
	conn->udp_target.sin_addr.s_addr = ((struct sockaddr_in *)(ptr->ai_addr))->sin_addr.s_addr;
	conn->udp_target.sin_port = htons(60000);

	// Connect to host. Because the socket is nonblocking, this
	// will always return WSAEWOULDBLOCK.
	connect(conn->sock, ptr->ai_addr, (int)ptr->ai_addrlen);
	freeaddrinfo(result);

	if (WSAGetLastError() != WSAEWOULDBLOCK) {
		log_socket_error(d, "connect");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	// Wait for connection.
	fd_set set;
	FD_ZERO(&set);
	FD_SET(conn->sock, &set);
	struct timeval time;
	time.tv_sec = 0;
	time.tv_usec = DEFAULT_TIMEOUT;
	res = select(0, &set, &set, &set, &time);

	if (res == SOCKET_ERROR) {
		log_socket_error(d, "select");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	} else if (res == 0) {
		trace(d, "Connection to %s timed out.\n", host);
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	// See if we have *actually* connected
	int error;
	int len = sizeof(error);
	if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *)&error, &len) ==
			SOCKET_ERROR) {
		log_socket_error(d, "getsockopt");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	if (error) {
		WSASetLastError(error);
		log_socket_error(d, "connect");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	BOOL ndelay = 1;
	res = setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
		(char *)&ndelay, sizeof(ndelay));
	if (res == SOCKET_ERROR) {
		log_socket_error(d, "setsockopt TCP_NODELAY");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	trace(d, "Connected.\n");

	// Create socket for OSC
	conn->udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (conn->udp_sock == INVALID_SOCKET) {
		log_socket_error(d, "socket(AF_INET, SOCK_DRGAM)");
	} else {
		res = connect(conn->udp_sock, (struct sockaddr *)&conn->udp_target, sizeof(conn->udp_target));
		if (res == SOCKET_ERROR) {
			log_socket_error(d, "connect(udp_sock)");
		}
	}

	nonblocking = 1;
	ioctlsocket(conn->udp_sock, FIONBIO, &nonblocking);

	// After we connect, the host will send an initial status response. 
	dac_read_resp(d, DEFAULT_TIMEOUT);
	dac_dump_resp(d);

	char c = 'p';
	dac_sendall(d, &c, 1);
	dac_read_resp(d, DEFAULT_TIMEOUT);
	dac_dump_resp(d);

	if (d->sw_revision >= 2) {
		c = 'v';
		dac_sendall(d, &c, 1);
		res = dac_read_bytes(d, d->version, sizeof(d->version));
		if (res < 0)
			return res;

		trace(d, "DAC version: %.*s\n", sizeof(d->version), d->version);
	} else {
		memset(d->version, 0, sizeof(d->version));
		trace(d, "DAC version old!\n");
	}

	return 0;
}
Exemplo n.º 11
0
/* Initialize a dac_conn_t and connect to the DAC.
 *
 * On success, return 0.
 */
int dac_connect(dac_t *d, const char *host, const char *port) {
	dac_conn_t *conn = &d->conn;
	ZeroMemory(conn, sizeof(d->conn));

	// Look up the server address
	struct addrinfo *result = NULL, *ptr = NULL, hints;
	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	flogd(d, "Calling getaddrinfo: \"%s\", \"%s\"\n", host, port);

	int res = getaddrinfo(host, port, &hints, &result);
	if (res != 0) {
		flogd(d, "getaddrinfo failed: %d\n", res);
		return -1;
	}

	// Create a SOCKET
	ptr = result;
	conn->sock = socket(ptr->ai_family, ptr->ai_socktype, 
		ptr->ai_protocol);

	if (conn->sock == INVALID_SOCKET) {
		log_socket_error(d, "socket");
		freeaddrinfo(result);
		return -1;
	}

	unsigned long nonblocking = 1;
	ioctlsocket(conn->sock, FIONBIO, &nonblocking);

	// Connect to host. Because the socket is nonblocking, this
	// will always return WSAEWOULDBLOCK.
	connect(conn->sock, ptr->ai_addr, (int)ptr->ai_addrlen);
	freeaddrinfo(result);

	if (WSAGetLastError() != WSAEWOULDBLOCK) {
		log_socket_error(d, "connect");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	// Wait for connection.
	fd_set set;
	FD_ZERO(&set);
	FD_SET(conn->sock, &set);
	struct timeval time;
	time.tv_sec = 0;
	time.tv_usec = DEFAULT_TIMEOUT;
	res = select(0, &set, &set, &set, &time);

	if (res == SOCKET_ERROR) {
		log_socket_error(d, "select");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	} else if (res == 0) {
		flogd(d, "Connection to %s timed out.\n", host);
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	// See if we have *actually* connected
	int error;
	int len = sizeof(error);
	if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *)&error, &len) ==
			SOCKET_ERROR) {
		log_socket_error(d, "getsockopt");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	if (error) {
		WSASetLastError(error);
		log_socket_error(d, "connect");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	BOOL ndelay = 1;
	res = setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
		(char *)&ndelay, sizeof(ndelay));
	if (res == SOCKET_ERROR) {
		log_socket_error(d, "setsockopt");
		closesocket(conn->sock);
		conn->sock = INVALID_SOCKET;
		return -1;
	}

	flogd(d, "Connected.\n");

	// After we connect, the host will send an initial status response. 
	dac_read_resp(d, DEFAULT_TIMEOUT);
	dac_dump_resp(d);

	char c = 'p';
	dac_sendall(d, &c, 1);
	dac_read_resp(d, DEFAULT_TIMEOUT);
	dac_dump_resp(d);

	flogd(d, "Sent.\n");

	return 0;
}
Exemplo n.º 12
0
void notify_thread(LIBEVENT_THREAD *thread) {
    if (send(thread->notify[1], "", 1, 0) != 1) {
        log_socket_error(EXTENSION_LOG_WARNING, NULL,
                         "Failed to notify thread: %s");
    }
}