mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-05-02 08:43:20 +00:00
PhySocket NULL check added to handle_write. Fixed after-close handle_write segfault
This commit is contained in:
parent
8e7e409fce
commit
b203d25656
@ -166,7 +166,7 @@ int get_retval()
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dwr("unable to read connect: return value\n");
|
dwr("unable to read return value\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ int getsockopt(GETSOCKOPT_SIG)
|
|||||||
|
|
||||||
int socket(SOCKET_SIG)
|
int socket(SOCKET_SIG)
|
||||||
{
|
{
|
||||||
//dwr("socket()*:\n");
|
dwr("socket()*:\n");
|
||||||
int err;
|
int err;
|
||||||
#ifdef CHECKS
|
#ifdef CHECKS
|
||||||
/* Check that type makes sense */
|
/* Check that type makes sense */
|
||||||
@ -375,6 +375,11 @@ int socket(SOCKET_SIG)
|
|||||||
|
|
||||||
char cmd[BUF_SZ];
|
char cmd[BUF_SZ];
|
||||||
fdret_sock = !is_initialized ? init_service_connection() : fdret_sock;
|
fdret_sock = !is_initialized ? init_service_connection() : fdret_sock;
|
||||||
|
if(fdret_sock < 0)
|
||||||
|
{
|
||||||
|
dwr("BAD service connection. exiting.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
if(socket_family == AF_LOCAL
|
if(socket_family == AF_LOCAL
|
||||||
|| socket_family == AF_NETLINK
|
|| socket_family == AF_NETLINK
|
||||||
@ -405,18 +410,21 @@ int socket(SOCKET_SIG)
|
|||||||
memset(cmd, '\0', BUF_SZ);
|
memset(cmd, '\0', BUF_SZ);
|
||||||
cmd[0] = RPC_FD_MAP_COMPLETION;
|
cmd[0] = RPC_FD_MAP_COMPLETION;
|
||||||
memcpy(&cmd[1], &newfd, sizeof(newfd));
|
memcpy(&cmd[1], &newfd, sizeof(newfd));
|
||||||
if(newfd > -1) {
|
|
||||||
|
//if(newfd > -1) {
|
||||||
send_command(fdret_sock, cmd);
|
send_command(fdret_sock, cmd);
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
errno = ERR_OK; // OK
|
errno = ERR_OK; // OK
|
||||||
return newfd;
|
return newfd;
|
||||||
}
|
//}
|
||||||
|
/*
|
||||||
else { // Try to read retval+errno since we RXed a bad fd
|
else { // Try to read retval+errno since we RXed a bad fd
|
||||||
dwr("Error, service sent bad fd.\n");
|
dwr("Error, service sent bad fd.\n");
|
||||||
err = get_retval();
|
err = get_retval();
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dwr("Error while receiving new FD.\n");
|
dwr("Error while receiving new FD.\n");
|
||||||
@ -434,7 +442,7 @@ int socket(SOCKET_SIG)
|
|||||||
connect() intercept function */
|
connect() intercept function */
|
||||||
int connect(CONNECT_SIG)
|
int connect(CONNECT_SIG)
|
||||||
{
|
{
|
||||||
//dwr("connect()*:\n");
|
dwr("connect()*:\n");
|
||||||
struct sockaddr_in *connaddr;
|
struct sockaddr_in *connaddr;
|
||||||
connaddr = (struct sockaddr_in *) __addr;
|
connaddr = (struct sockaddr_in *) __addr;
|
||||||
|
|
||||||
@ -520,7 +528,7 @@ int select(SELECT_SIG)
|
|||||||
bind() intercept function */
|
bind() intercept function */
|
||||||
int bind(BIND_SIG)
|
int bind(BIND_SIG)
|
||||||
{
|
{
|
||||||
//dwr("bind()*:\n");
|
dwr("bind()*:\n");
|
||||||
#ifdef CHECKS
|
#ifdef CHECKS
|
||||||
/* Check that this is a valid fd */
|
/* Check that this is a valid fd */
|
||||||
if(fcntl(sockfd, F_GETFD) < 0) {
|
if(fcntl(sockfd, F_GETFD) < 0) {
|
||||||
@ -582,7 +590,7 @@ int bind(BIND_SIG)
|
|||||||
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
|
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
|
||||||
int accept4(ACCEPT4_SIG)
|
int accept4(ACCEPT4_SIG)
|
||||||
{
|
{
|
||||||
//dwr("accept4()*:\n");
|
dwr("accept4()*:\n");
|
||||||
#ifdef CHECKS
|
#ifdef CHECKS
|
||||||
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
|
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -608,7 +616,7 @@ int accept4(ACCEPT4_SIG)
|
|||||||
accept() intercept function */
|
accept() intercept function */
|
||||||
int accept(ACCEPT_SIG)
|
int accept(ACCEPT_SIG)
|
||||||
{
|
{
|
||||||
//dwr("accept()*:\n");
|
dwr("accept()*:\n");
|
||||||
#ifdef CHECKS
|
#ifdef CHECKS
|
||||||
/* Check that this is a valid fd */
|
/* Check that this is a valid fd */
|
||||||
if(fcntl(sockfd, F_GETFD) < 0) {
|
if(fcntl(sockfd, F_GETFD) < 0) {
|
||||||
@ -701,7 +709,7 @@ int accept(ACCEPT_SIG)
|
|||||||
listen() intercept function */
|
listen() intercept function */
|
||||||
int listen(LISTEN_SIG)
|
int listen(LISTEN_SIG)
|
||||||
{
|
{
|
||||||
//dwr("listen()*:\n");
|
dwr("listen()*:\n");
|
||||||
#ifdef CHECKS
|
#ifdef CHECKS
|
||||||
/* Check that this is a valid fd */
|
/* Check that this is a valid fd */
|
||||||
if(fcntl(sockfd, F_GETFD) < 0) {
|
if(fcntl(sockfd, F_GETFD) < 0) {
|
||||||
|
@ -276,7 +276,7 @@ void NetconEthernetTap::closeConnection(TcpConnection *conn)
|
|||||||
close(conn->their_fd);
|
close(conn->their_fd);
|
||||||
if(conn->dataSock) {
|
if(conn->dataSock) {
|
||||||
close(_phy.getDescriptor(conn->dataSock));
|
close(_phy.getDescriptor(conn->dataSock));
|
||||||
_phy.close(conn->dataSock);
|
_phy.close(conn->dataSock,false);
|
||||||
}
|
}
|
||||||
for(int i=0; i<tcp_connections.size(); i++) {
|
for(int i=0; i<tcp_connections.size(); i++) {
|
||||||
if(tcp_connections[i] == conn) {
|
if(tcp_connections[i] == conn) {
|
||||||
@ -918,14 +918,13 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
|
|||||||
fprintf(stderr, "handle_listen(): PCB is already in listening state.\n");
|
fprintf(stderr, "handle_listen(): PCB is already in listening state.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tcp_pcb* listening_pcb;
|
struct tcp_pcb* listening_pcb;
|
||||||
|
|
||||||
#ifdef TCP_LISTEN_BACKLOG
|
#ifdef TCP_LISTEN_BACKLOG
|
||||||
listening_pcb = lwipstack->tcp_listen_with_backlog(conn->pcb, listen_rpc->backlog);
|
listening_pcb = lwipstack->tcp_listen_with_backlog(conn->pcb, listen_rpc->backlog);
|
||||||
#else
|
#else
|
||||||
listening_pcb = lwipstack->tcp_listen(conn->pcb);
|
listening_pcb = lwipstack->tcp_listen(conn->pcb);
|
||||||
#endif
|
#endif
|
||||||
// FIXME: Correct return values from this method, most is handled in intercept lib
|
|
||||||
|
|
||||||
if(listening_pcb != NULL) {
|
if(listening_pcb != NULL) {
|
||||||
conn->pcb = listening_pcb;
|
conn->pcb = listening_pcb;
|
||||||
@ -1146,34 +1145,36 @@ void NetconEthernetTap::handle_write(TcpConnection *conn)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_fd = _phy.getDescriptor(conn->dataSock);
|
if(conn->dataSock) {
|
||||||
if((r = read(read_fd, (&conn->buf)+conn->idx, sndbuf)) > 0) {
|
int read_fd = _phy.getDescriptor(conn->dataSock);
|
||||||
conn->idx += r;
|
if((r = read(read_fd, (&conn->buf)+conn->idx, sndbuf)) > 0) {
|
||||||
/* Writes data pulled from the client's socket buffer to LWIP. This merely sends the
|
conn->idx += r;
|
||||||
* data to LWIP to be enqueued and eventually sent to the network. */
|
/* Writes data pulled from the client's socket buffer to LWIP. This merely sends the
|
||||||
if(r > 0) {
|
* data to LWIP to be enqueued and eventually sent to the network. */
|
||||||
int sz;
|
if(r > 0) {
|
||||||
// NOTE: this assumes that lwipstack->_lock is locked, either
|
int sz;
|
||||||
// because we are in a callback or have locked it manually.
|
// NOTE: this assumes that lwipstack->_lock is locked, either
|
||||||
int err = lwipstack->_tcp_write(conn->pcb, &conn->buf, r, TCP_WRITE_FLAG_COPY);
|
// because we are in a callback or have locked it manually.
|
||||||
//lwipstack->_tcp_output(conn->pcb);
|
int err = lwipstack->_tcp_write(conn->pcb, &conn->buf, r, TCP_WRITE_FLAG_COPY);
|
||||||
if(err != ERR_OK) {
|
//lwipstack->_tcp_output(conn->pcb);
|
||||||
fprintf(stderr, "handle_write(): error while writing to PCB, (err = %d)\n", err);
|
if(err != ERR_OK) {
|
||||||
return;
|
fprintf(stderr, "handle_write(): error while writing to PCB, (err = %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sz = (conn->idx)-r;
|
||||||
|
if(sz) {
|
||||||
|
memmove(&conn->buf, (conn->buf+r), sz);
|
||||||
|
}
|
||||||
|
conn->idx -= r;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sz = (conn->idx)-r;
|
fprintf(stderr, "handle_write(): LWIP stack full\n");
|
||||||
if(sz) {
|
|
||||||
memmove(&conn->buf, (conn->buf+r), sz);
|
|
||||||
}
|
|
||||||
conn->idx -= r;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
fprintf(stderr, "handle_write(): LWIP stack full\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
Network Containers have been tested with the following:
|
Network Containers have been tested with the following:
|
||||||
|
|
||||||
sshd [ WORKS as of 20151010] Long ~15-20s delay for client during connect
|
sshd [ WORKS as of 20151022] Long ~15-20s delay for client during connect
|
||||||
ssh [ WORKS as of 20151010]
|
ssh [ WORKS as of 20151022]
|
||||||
curl [ WORKS as of 20151021]
|
sftp [ WORKS as of 20151022]
|
||||||
|
curl [ WORKS as of 20151021] Sometimes "tcp_input: pcb->next != pcb (before cache)" is seen
|
||||||
apache (debug mode) [ WORKS as of 2015xxxx]
|
apache (debug mode) [ WORKS as of 2015xxxx]
|
||||||
apache (prefork MPM) [ WORKS as of 20151021]
|
apache (prefork MPM) [ WORKS as of 20151021]
|
||||||
nginx [ WORKS as of 2015xxxx]
|
nginx [ WORKS as of 20151022]
|
||||||
nodejs [ WORKS as of 20151021]
|
nodejs [ WORKS as of 20151021]
|
||||||
java [ WORKS as of 2015xxxx]
|
java [ WORKS as of 2015xxxx]
|
||||||
tomcat [ WORKS as of 2015xxxx]
|
tomcat [ WORKS as of 2015xxxx]
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user