int lazy_operation_addlayer (unsigned int layer_id, unsigned int buffer_id, int width, int height, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh) { lazy_operation_addlayer_t op; lazy_operation_addlayer_res_t ret; memset (&op, 0, sizeof (op)); op.operation = LAZY_OPERATION_ADD_LAYER; op.layer_id = layer_id; op.width = width; op.height = height; op.src.x = sx; op.src.y = sy; op.src.w = sw; op.src.h = sh; op.dst.x = dx; op.dst.y = dy; op.dst.w = dw; op.dst.h = dh; op.buffer_id = buffer_id; SOCKET_LOCK (); if (write (socket_fd, &op, sizeof (op)) != sizeof (op)) { perror ("write"); goto addlayer_fail; } if (read (socket_fd, &ret, sizeof (ret)) != sizeof (ret)) { perror ("read"); goto addlayer_fail; } if (ret.result != LAZY_OPERATION_RESULT_SUCCESS) goto addlayer_fail; SOCKET_UNLOCK (); return 1; addlayer_fail: SOCKET_UNLOCK (); return 0; }
void lazy_operation_fini (void) { SOCKET_LOCK (); close (socket_fd); socket_fd = -1; SOCKET_UNLOCK (); }
void lazy_operation_init (void) { struct sockaddr_in sv_addr; struct hostent *host; SOCKET_LOCK (); if (socket_fd != -1) { socket_fd = -1; close (socket_fd); } /* Resolv name */ if (!(host = gethostbyname (LAZY_PASSTHROUGH_HOST))) { SOCKET_UNLOCK (); return; } memset (&sv_addr, 0, sizeof (struct sockaddr_in)); sv_addr.sin_family = AF_INET; sv_addr.sin_addr = *((struct in_addr *) host->h_addr); sv_addr.sin_port = htons (LAZY_PASSTHROUGH_PORT); if ((socket_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP)) >= 0) { if (connect (socket_fd, (struct sockaddr *) &sv_addr, sizeof (struct sockaddr)) < 0) { perror ("connect"); close (socket_fd); } } else perror ("socket"); SOCKET_UNLOCK (); }
int lazy_operation_addbuffer (int width, int height, int bpp, unsigned int *buffer_id) { lazy_operation_addbuffer_t op; lazy_operation_addbuffer_res_t ret; memset (&op, 0, sizeof (op)); op.operation = LAZY_OPERATION_ADD_BUFFER; op.width = width; op.height = height; op.bpp = bpp; SOCKET_LOCK (); if (write (socket_fd, &op, sizeof (op)) != sizeof (op)) { perror ("write"); goto addlayer_fail; } if (read (socket_fd, &ret, sizeof (ret)) != sizeof (ret)) { perror ("read"); goto addlayer_fail; } if (ret.result != LAZY_OPERATION_RESULT_SUCCESS) goto addlayer_fail; SOCKET_UNLOCK (); *buffer_id = ret.buffer_id; return 1; addlayer_fail: SOCKET_UNLOCK (); return 0; }
int lazy_operation_fliplayer (unsigned int layer_id, unsigned int buffer_id) { lazy_operation_fliplayer_t op; lazy_operation_fliplayer_res_t ret; memset (&op, 0, sizeof (op)); op.operation = LAZY_OPERATION_FLIP_LAYER; op.layer_id = layer_id; op.buffer_id = buffer_id; SOCKET_LOCK (); if (write (socket_fd, &op, sizeof (op)) != sizeof (op)) { perror ("write"); goto addlayer_fail; } if (read (socket_fd, &ret, sizeof (ret)) != sizeof (ret)) { perror ("read"); goto addlayer_fail; } if (ret.result != LAZY_OPERATION_RESULT_SUCCESS) goto addlayer_fail; SOCKET_UNLOCK (); return 1; addlayer_fail: SOCKET_UNLOCK (); return 0; }
void udp_detach(PNATState pData, struct socket *so) { if (so != &pData->icmp_socket) { Assert(so->so_type == IPPROTO_UDP); QSOCKET_LOCK(udb); SOCKET_LOCK(so); QSOCKET_UNLOCK(udb); closesocket(so->s); sofree(pData, so); SOCKET_UNLOCK(so); } }
void udp_detach(PNATState pData, struct socket *so) { if (so != &pData->icmp_socket) { Assert(so->so_type == IPPROTO_UDP); QSOCKET_LOCK(udb); SOCKET_LOCK(so); QSOCKET_UNLOCK(udb); #ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE if (so->so_cloneOf) so->so_cloneOf->so_cCloneCounter--; else if (so->so_cCloneCounter > 0) { /* we can't close socket yet */ SOCKET_UNLOCK(so); return; } #endif closesocket(so->s); sofree(pData, so); SOCKET_UNLOCK(so); } }
/* * Read from so's socket into sb_snd, updating all relevant sbuf fields * NOTE: This will only be called if it is select()ed for reading, so * a read() of 0 (or less) means it's disconnected */ int soread(PNATState pData, struct socket *so) { int n, nn, lss, total; struct sbuf *sb = &so->so_snd; u_int len = sb->sb_datalen - sb->sb_cc; struct iovec iov[2]; int mss = so->so_tcpcb->t_maxseg; int sockerr; STAM_PROFILE_START(&pData->StatIOread, a); STAM_COUNTER_RESET(&pData->StatIORead_in_1); STAM_COUNTER_RESET(&pData->StatIORead_in_2); QSOCKET_LOCK(tcb); SOCKET_LOCK(so); QSOCKET_UNLOCK(tcb); LogFlow(("soread: so = %R[natsock]\n", so)); Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, so, sb)); /* * No need to check if there's enough room to read. * soread wouldn't have been called if there weren't */ len = sb->sb_datalen - sb->sb_cc; iov[0].iov_base = sb->sb_wptr; iov[1].iov_base = 0; iov[1].iov_len = 0; if (sb->sb_wptr < sb->sb_rptr) { iov[0].iov_len = sb->sb_rptr - sb->sb_wptr; /* Should never succeed, but... */ if (iov[0].iov_len > len) iov[0].iov_len = len; if (iov[0].iov_len > mss) iov[0].iov_len -= iov[0].iov_len%mss; n = 1; } else { iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr; /* Should never succeed, but... */ if (iov[0].iov_len > len) iov[0].iov_len = len; len -= iov[0].iov_len; if (len) { iov[1].iov_base = sb->sb_data; iov[1].iov_len = sb->sb_rptr - sb->sb_data; if (iov[1].iov_len > len) iov[1].iov_len = len; total = iov[0].iov_len + iov[1].iov_len; if (total > mss) { lss = total % mss; if (iov[1].iov_len > lss) { iov[1].iov_len -= lss; n = 2; } else { lss -= iov[1].iov_len; iov[0].iov_len -= lss; n = 1; } } else n = 2; } else { if (iov[0].iov_len > mss) iov[0].iov_len -= iov[0].iov_len%mss; n = 1; } } #ifdef HAVE_READV nn = readv(so->s, (struct iovec *)iov, n); #else nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, (so->so_tcpcb->t_force? MSG_OOB:0)); #endif if (nn < 0) sockerr = errno; /* save it, as it may be clobbered by logging */ else sockerr = 0; Log2(("%s: read(1) nn = %d bytes\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, nn)); Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, so, sb)); if (nn <= 0) { #ifdef RT_OS_WINDOWS /* * Windows reports ESHUTDOWN after SHUT_RD (SD_RECEIVE) * instead of just returning EOF indication. */ if (nn < 0 && sockerr == ESHUTDOWN) { nn = 0; sockerr = 0; } #endif if (nn == 0) /* XXX: should this be inside #if defined(RT_OS_WINDOWS)? */ { /* * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that * _could_ mean that the connection is closed. But we will receive an * FD_CLOSE event later if the connection was _really_ closed. With * www.youtube.com I see this very often. Closing the socket too early * would be dangerous. */ int status; unsigned long pending = 0; status = ioctlsocket(so->s, FIONREAD, &pending); if (status < 0) Log(("NAT:%s: error in WSAIoctl: %d\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, errno)); if (pending != 0) { SOCKET_UNLOCK(so); STAM_PROFILE_STOP(&pData->StatIOread, a); return 0; } } if ( nn < 0 && soIgnorableErrorCode(sockerr)) { SOCKET_UNLOCK(so); STAM_PROFILE_STOP(&pData->StatIOread, a); return 0; } else { int fUninitializedTemplate = 0; int shuterr; fUninitializedTemplate = RT_BOOL(( sototcpcb(so) && ( sototcpcb(so)->t_template.ti_src.s_addr == INADDR_ANY || sototcpcb(so)->t_template.ti_dst.s_addr == INADDR_ANY))); /* nn == 0 means peer has performed an orderly shutdown */ Log2(("%s: disconnected, nn = %d, errno = %d (%s)\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, nn, sockerr, strerror(sockerr))); shuterr = sofcantrcvmore(so); if (!sockerr && !shuterr && !fUninitializedTemplate) tcp_sockclosed(pData, sototcpcb(so)); else { LogRel2(("NAT: sockerr %d, shuterr %d - %R[natsock]\n", sockerr, shuterr, so)); tcp_drop(pData, sototcpcb(so), sockerr); } SOCKET_UNLOCK(so); STAM_PROFILE_STOP(&pData->StatIOread, a); return -1; } } STAM_STATS( if (n == 1) { STAM_COUNTER_INC(&pData->StatIORead_in_1); STAM_COUNTER_ADD(&pData->StatIORead_in_1_bytes, nn); } else { STAM_COUNTER_INC(&pData->StatIORead_in_2); STAM_COUNTER_ADD(&pData->StatIORead_in_2_1st_bytes, nn); } );