This is an automated email from the git hooks/post-receive script. x2go pushed a change to branch feature/udp-support in repository x2gokdrive. from dfc7320 Server to client selection in UDP mode. new bc9fa19 Send only frames over UDP The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Summary of changes: x2gokdriveremote.c | 969 ++++++++++------------------------------------------- x2gokdriveremote.h | 64 +--- 2 files changed, 194 insertions(+), 839 deletions(-) -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gokdrive.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch feature/udp-support in repository x2gokdrive. commit bc9fa19708e26dc9aa5608fcadd9b9692a5b0b3c Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Tue Dec 20 09:10:48 2022 -0600 Send only frames over UDP --- x2gokdriveremote.c | 969 ++++++++++------------------------------------------- x2gokdriveremote.h | 64 +--- 2 files changed, 194 insertions(+), 839 deletions(-) diff --git a/x2gokdriveremote.c b/x2gokdriveremote.c index 3d0f879..ba4a3c2 100644 --- a/x2gokdriveremote.c +++ b/x2gokdriveremote.c @@ -388,14 +388,7 @@ void remote_sendVersion(void) *((uint32_t*)buffer)=SERVERVERSION; //4B *((uint16_t*)buffer+2)=FEATURE_VERSION; EPHYR_DBG("Sending server version: %d", FEATURE_VERSION); - if(remoteVars.serverType==TCP) - { - l=write(remoteVars.clientsock,buffer,56); - } - else - { - l=send_packet_as_datagrams(buffer, 6, ServerSyncPacket); - } + l=write(remoteVars.clientsock_tcp,buffer,56); remoteVars.server_version_sent=TRUE; } @@ -406,10 +399,7 @@ void request_selection_from_client(enum SelectionType selection) *((uint32_t*)buffer)=DEMANDCLIENTSELECTION; //4B *((uint16_t*)buffer+2)=(uint16_t)selection; - if(remoteVars.serverType==TCP) - l=write(remoteVars.clientsock,buffer,56); - else - l=send_packet_as_datagrams(buffer, 6, ServerControlPacket); + l=write(remoteVars.clientsock_tcp,buffer,56); EPHYR_DBG("requesting selection from client"); } @@ -421,19 +411,8 @@ int32_t send_cursor(struct cursorFrame* cursor) _X_UNUSED int ln = 0; int l = 0; int sent = 0; - int total = 0; - int hdr_sz=7*4; - if(remoteVars.serverType==UDP) - { - //packet size: header size + data size - total=hdr_sz +cursor->size; - buffer=malloc(total); - } - else - { - buffer=static_buffer; - } + buffer=static_buffer; *((uint32_t*)buffer)=CURSOR; //4B @@ -456,26 +435,17 @@ int32_t send_cursor(struct cursorFrame* cursor) // EPHYR_DBG("SENDING CURSOR %d with size %d", cursor->serialNumber, cursor->size); // #warning check this - if(remoteVars.serverType==TCP) - { - ln=write(remoteVars.clientsock,buffer,56); + ln=write(remoteVars.clientsock_tcp,buffer,56); - while(sent<cursor->size) + while(sent<cursor->size) + { + l=write(remoteVars.clientsock_tcp, cursor->data+sent,((cursor->size-sent)<MAXMSGSIZE)?(cursor->size-sent):MAXMSGSIZE); + if(l<0) { - l=write(remoteVars.clientsock, cursor->data+sent,((cursor->size-sent)<MAXMSGSIZE)?(cursor->size-sent):MAXMSGSIZE); - if(l<0) - { - EPHYR_DBG("Error sending cursor!!!!!"); - break; - } - sent+=l; + EPHYR_DBG("Error sending cursor!!!!!"); + break; } - } - else - { - memcpy(buffer+hdr_sz, cursor->data, cursor->size); - sent=send_packet_as_datagrams(buffer, total, ServerControlPacket); - free(buffer); + sent+=l; } remoteVars.data_sent+=sent; // EPHYR_DBG("SENT total %d", total); @@ -507,7 +477,7 @@ int32_t send_frame(u_int32_t width, uint32_t height, uint32_t x, uint32_t y, uin } //calculating total size of the data need to be sent - if(remoteVars.serverType==UDP) + if(remoteVars.send_frames_over_udp) { //frame header size total=header_size; @@ -541,9 +511,9 @@ int32_t send_frame(u_int32_t width, uint32_t height, uint32_t x, uint32_t y, uin }*/ } - if(remoteVars.serverType==TCP) + if(!remoteVars.send_frames_over_udp) { - ln=write(remoteVars.clientsock, buffer,56); + ln=write(remoteVars.clientsock_tcp, buffer,56); } else { @@ -569,7 +539,7 @@ int32_t send_frame(u_int32_t width, uint32_t height, uint32_t x, uint32_t y, uin *((uint32_t*)head_buffer+6)=regions[i].rect.size.height; *((uint32_t*)head_buffer+7)=regions[i].size; - if(remoteVars.serverType==UDP) + if(remoteVars.send_frames_over_udp) { //increment offset on region header size head_buffer+=region_header_size; @@ -581,11 +551,11 @@ int32_t send_frame(u_int32_t width, uint32_t height, uint32_t x, uint32_t y, uin { sent = 0; // #warning check this - ln=write(remoteVars.clientsock, buffer, 64); + ln=write(remoteVars.clientsock_tcp, buffer, 64); while(sent<regions[i].size) { - l=write(remoteVars.clientsock,regions[i].compressed_data+sent, + l=write(remoteVars.clientsock_tcp,regions[i].compressed_data+sent, ((regions[i].size-sent)<MAXMSGSIZE)?(regions[i].size-sent):MAXMSGSIZE); if(l<0) { @@ -603,7 +573,7 @@ int32_t send_frame(u_int32_t width, uint32_t height, uint32_t x, uint32_t y, uin } } //if proto TCP all data is sent at this moment - if(remoteVars.serverType==UDP) + if(remoteVars.send_frames_over_udp) { if(remoteVars.compression==JPEG) { @@ -630,8 +600,6 @@ int send_deleted_elements(void) unsigned char* buffer; unsigned char static_buffer[56] = {0}; unsigned char* list = NULL; - int total = 0; - int hdr_sz=2*4; _X_UNUSED int ln = 0; int l = 0; @@ -641,16 +609,7 @@ int send_deleted_elements(void) struct deleted_elem* elem = NULL; length=remoteVars.deleted_list_size*sizeof(uint32_t); - if(remoteVars.serverType==UDP) - { - //packet size: header size + data size - total=hdr_sz + length; - buffer=malloc(total); - } - else - { - buffer=static_buffer; - } + buffer=static_buffer; *((uint32_t*)buffer)=DELETED; @@ -671,26 +630,17 @@ int send_deleted_elements(void) remoteVars.last_deleted_elements=0l; -// EPHYR_DBG("SENDING IMG length - %d, number - %d\n",length,framenum_sent++); - if(remoteVars.serverType==TCP) + // EPHYR_DBG("SENDING IMG length - %d, number - %d\n",length,framenum_sent++); + ln=write(remoteVars.clientsock_tcp,buffer,56); + while(sent<length) { - ln=write(remoteVars.clientsock,buffer,56); - while(sent<length) + l=write(remoteVars.clientsock_tcp,list+sent,((length-sent)<MAXMSGSIZE)?(length-sent):MAXMSGSIZE); + if(l<0) { - l=write(remoteVars.clientsock,list+sent,((length-sent)<MAXMSGSIZE)?(length-sent):MAXMSGSIZE); - if(l<0) - { - EPHYR_DBG("Error sending list of deleted elements!!!!!"); - break; - } - sent+=l; + EPHYR_DBG("Error sending list of deleted elements!!!!!"); + break; } - } - else - { - memcpy(buffer+hdr_sz, list, length); - sent=send_packet_as_datagrams(buffer, total, ServerControlPacket); - free(buffer); + sent+=l; } remoteVars.deleted_list_size=0; free(list); @@ -703,8 +653,6 @@ int send_deleted_cursors(void) unsigned char* buffer; unsigned char static_buffer[56] = {0}; unsigned char* list = NULL; - int total = 0; - int hdr_sz=2*4; _X_UNUSED int ln = 0; int l = 0; @@ -714,16 +662,7 @@ int send_deleted_cursors(void) struct deletedCursor* elem = NULL; length=remoteVars.deletedcursor_list_size*sizeof(uint32_t); - if(remoteVars.serverType==UDP) - { - //packet size: header size + data size - total=hdr_sz + length; - buffer=malloc(total); - } - else - { - buffer=static_buffer; - } + buffer=static_buffer; *((uint32_t*)buffer)=DELETEDCURSOR; @@ -746,25 +685,16 @@ int send_deleted_cursors(void) remoteVars.last_deleted_cursor=0l; // EPHYR_DBG("Sending list from %d elements", deletedcursor_list_size); - if(remoteVars.serverType==TCP) + ln=write(remoteVars.clientsock_tcp,buffer,56); + while(sent<length) { - ln=write(remoteVars.clientsock,buffer,56); - while(sent<length) + l=write(remoteVars.clientsock_tcp,list+sent,((length-sent)<MAXMSGSIZE)?(length-sent):MAXMSGSIZE); + if(l<0) { - l=write(remoteVars.clientsock,list+sent,((length-sent)<MAXMSGSIZE)?(length-sent):MAXMSGSIZE); - if(l<0) - { - EPHYR_DBG("Error sending list of deleted cursors!!!!!"); - break; - } - sent+=l; + EPHYR_DBG("Error sending list of deleted cursors!!!!!"); + break; } - } - else - { - memcpy(buffer+hdr_sz, list, length); - sent=send_packet_as_datagrams(buffer, total, ServerControlPacket); - free(buffer); + sent+=l; } free(list); @@ -799,10 +729,7 @@ void send_reinit_notification(void) _X_UNUSED int l; *((uint32_t*)buffer)=REINIT; EPHYR_DBG("SENDING REINIT NOTIFICATION"); - if(remoteVars.serverType==TCP) - l=write(remoteVars.clientsock,buffer,56); - else - l=send_packet_as_datagrams(buffer,4,ServerControlPacket); + l=write(remoteVars.clientsock_tcp,buffer,56); } int send_selection_chunk(int sel, unsigned char* data, uint32_t length, uint32_t format, BOOL first, BOOL last, uint32_t compressed, uint32_t total_sz) @@ -813,8 +740,6 @@ int send_selection_chunk(int sel, unsigned char* data, uint32_t length, uint32_t _X_UNUSED int ln = 0; int l = 0; int sent = 0; - int total = 0; - int hdr_sz=8*4; uint32_t uncompressed_length=length; //if the data is compressed, send "compressed" amount of bytes @@ -824,16 +749,7 @@ int send_selection_chunk(int sel, unsigned char* data, uint32_t length, uint32_t length=compressed; } - if(remoteVars.serverType==UDP) - { - //packet size: header size + data size - total=hdr_sz +length; - buffer=malloc(total); - } - else - { - buffer=static_buffer; - } + buffer=static_buffer; *((uint32_t*)buffer)=SELECTION; //0 *((uint32_t*)buffer+1)=sel; //4 @@ -846,25 +762,16 @@ int send_selection_chunk(int sel, unsigned char* data, uint32_t length, uint32_t - if(remoteVars.serverType==TCP) + ln=write(remoteVars.clientsock_tcp,buffer,56); + while(sent<length) { - ln=write(remoteVars.clientsock,buffer,56); - while(sent<length) + l=write(remoteVars.clientsock_tcp,data+sent,((length-sent)<MAXMSGSIZE)?(length-sent):MAXMSGSIZE); + if(l<0) { - l=write(remoteVars.clientsock,data+sent,((length-sent)<MAXMSGSIZE)?(length-sent):MAXMSGSIZE); - if(l<0) - { - EPHYR_DBG("Error sending selection!!!!!"); - break; - } - sent+=l; + EPHYR_DBG("Error sending selection!!!!!"); + break; } - } - else - { - memcpy(buffer+hdr_sz, data, length); - sent=send_packet_as_datagrams(buffer, total, ServerControlPacket); - free(buffer); + sent+=l; } return sent; } @@ -1675,11 +1582,11 @@ void remote_send_win_updates(char* updateBuf, uint32_t bufSize) *((uint32_t*)buffer)=WINUPDATE; *((uint32_t*)buffer+1)=bufSize; - l=write(remoteVars.clientsock,buffer,56); + l=write(remoteVars.clientsock_tcp,buffer,56); while(sent<bufSize) { - l=write(remoteVars.clientsock,updateBuf+sent,((bufSize-sent)<MAXMSGSIZE)?(bufSize-sent):MAXMSGSIZE); + l=write(remoteVars.clientsock_tcp,updateBuf+sent,((bufSize-sent)<MAXMSGSIZE)?(bufSize-sent):MAXMSGSIZE); if(l<0) { EPHYR_DBG("Error sending windows update!!!!!"); @@ -1851,14 +1758,11 @@ void *send_frame_thread (void *threadid) while(1) { - pthread_mutex_lock(&remoteVars.sendqueue_mutex); if(!remoteVars.client_connected) { EPHYR_DBG ("TCP connection closed\n"); - shutdown(remoteVars.clientsock, SHUT_RDWR); - close(remoteVars.clientsock); - + close_client_sockets(); pthread_mutex_unlock(&remoteVars.sendqueue_mutex); break; } @@ -2296,8 +2200,8 @@ void disconnect_client(void) setAgentState(SUSPENDED); clean_everything(); #if XORG_VERSION_CURRENT >= 11900000 - EPHYR_DBG("Remove notify FD for client sock %d",remoteVars.clientsock); - RemoveNotifyFd(remoteVars.clientsock); + EPHYR_DBG("Remove notify FD for client sock %d",remoteVars.clientsock_tcp); + RemoveNotifyFd(remoteVars.clientsock_tcp); #endif /* XORG_VERSION_CURRENT */ pthread_cond_signal(&remoteVars.have_sendqueue_cond); @@ -2692,20 +2596,7 @@ BOOL remote_process_client_event ( char* buff , int length) } case KEEPALIVE: { - //receive keepalive event. In UDP case we are also using it for synchronization - if(remoteVars.serverType==UDP) - { - int16_t lastContr=*((uint16_t*)buff+2); -// EPHYR_DBG("Client synchronization, last control packet %d, last frame packet %d", lastContr, lastFr); - pthread_mutex_lock(&remoteVars.server_dgram_mutex); - remove_dgram_from_list(&(remoteVars.server_control_datagrams), lastContr, FALSE); - pthread_mutex_unlock(&remoteVars.server_dgram_mutex); - } - break; - } - case RESENDSCONTROL: - { - resend_dgrams(buff+4,length-4, ServerControlPacket); + //receive keepalive event. break; } case RESENDFRAME: @@ -2730,6 +2621,11 @@ BOOL remote_process_client_event ( char* buff , int length) disconnect_client(); break; } + case OPENUDP: + { + open_udp_socket(); + break; + } default: { EPHYR_DBG("UNSUPPORTED EVENT: %d",event_type); @@ -2739,46 +2635,6 @@ BOOL remote_process_client_event ( char* buff , int length) return TRUE; } -void -resend_dgrams(char* buffer, int length, uint8_t dgType) -{ - int processed=0; - uint16_t packSeq; - uint16_t missedDgs; - uint16_t dgSeq; - uint16_t i; - while(processed<length) - { - packSeq=*( (uint16_t*) (buffer+processed) ); - processed+=2; - missedDgs=*( (uint16_t*) (buffer+processed) ); - processed+=2; - if(missedDgs) - { - EPHYR_DBG("Client missing %d datagrams, from packet %d, type %d",missedDgs, packSeq, dgType); - for(i=0;i<missedDgs;++i) - { - if(processed >= length) - { - EPHYR_DBG("WARNING, Client requested wrong amount of datagrams, stop processing..."); - send_sync_failed_notification(); - return; - } - dgSeq=*( (uint16_t*) (buffer+processed) ); - resend_dgram(dgType, packSeq, dgSeq); - processed+=2; - } - processed+=missedDgs*2; - } - else - { - EPHYR_DBG("Client missing packet %d, type %d", packSeq, dgType); - resend_dgram_packet(dgType, packSeq); - } - } -} - - void clientReadNotify(int fd, int ready, void *data) { @@ -2794,14 +2650,9 @@ clientReadNotify(int fd, int ready, void *data) pthread_mutex_unlock(&remoteVars.sendqueue_mutex); if(!con) return; - if(remoteVars.serverType==UDP) - { - remote_recv_dgram(); - return; - } /* read max 99 events */ - length=read(remoteVars.clientsock,remoteVars.eventBuffer + remoteVars.evBufferOffset, EVLENGTH*99); + length=read(remoteVars.clientsock_tcp,remoteVars.eventBuffer + remoteVars.evBufferOffset, EVLENGTH*99); if(length<0) { @@ -3176,61 +3027,57 @@ void serverAcceptNotify(int fd, int ready_sock, void *data) int length=32; int ready=0; - if(remoteVars.serverType==TCP) + + remoteVars.clientsock_tcp = accept ( remoteVars.serversock_tcp, (struct sockaddr *) &remoteVars.tcp_address, &remoteVars.tcp_addrlen); + if (remoteVars.clientsock_tcp <= 0) { - remoteVars.clientsock = accept ( remoteVars.serversock, (struct sockaddr *) &remoteVars.address, &remoteVars.addrlen ); - if (remoteVars.clientsock <= 0) - { - EPHYR_DBG( "ACCEPT ERROR OR CANCELD!\n"); - return; - } - EPHYR_DBG ("Connection from (%s)...\n", inet_ntoa (remoteVars.address.sin_addr)); + EPHYR_DBG( "ACCEPT ERROR OR CANCELD!\n"); + return; + } + EPHYR_DBG ("Connection from (%s)...\n", inet_ntoa (remoteVars.tcp_address.sin_addr)); - //only accept one client, close server socket - close_server_socket(); + //only accept one client, close server socket + close_server_socket(); - if(strlen(remoteVars.acceptAddr)) - { - struct addrinfo hints, *res; - int errcode; + if(strlen(remoteVars.acceptAddr)) + { + struct addrinfo hints, *res; + int errcode; - memset (&hints, 0, sizeof (hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags |= AI_CANONNAME; + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags |= AI_CANONNAME; - errcode = getaddrinfo (remoteVars.acceptAddr, NULL, &hints, &res); - if (errcode != 0 || !res) - { - EPHYR_DBG ("ERROR LOOKUP %s", remoteVars.acceptAddr); - terminateServer(-1); - } - if( ((struct sockaddr_in *) (res->ai_addr))->sin_addr.s_addr != remoteVars.address.sin_addr.s_addr) - { - EPHYR_DBG("Connection only allowed from %s",inet_ntoa ( ((struct sockaddr_in *)(res->ai_addr))->sin_addr)); - shutdown(remoteVars.clientsock, SHUT_RDWR); - close(remoteVars.clientsock); - return; - } + errcode = getaddrinfo (remoteVars.acceptAddr, NULL, &hints, &res); + if (errcode != 0 || !res) + { + EPHYR_DBG ("ERROR LOOKUP %s", remoteVars.acceptAddr); + terminateServer(-1); } - if(strlen(remoteVars.cookie)) + if( ((struct sockaddr_in *) (res->ai_addr))->sin_addr.s_addr != remoteVars.tcp_address.sin_addr.s_addr) { - while(ready<length) + EPHYR_DBG("Connection only allowed from %s",inet_ntoa ( ((struct sockaddr_in *)(res->ai_addr))->sin_addr)); + close_client_sockets(); + return; + } + } + if(strlen(remoteVars.cookie)) + { + while(ready<length) + { + int chunk=read(remoteVars.clientsock_tcp, msg+ready, 32-ready); + if(chunk<=0) { - int chunk=read(remoteVars.clientsock, msg+ready, 32-ready); - if(chunk<=0) - { - EPHYR_DBG("READ COOKIE ERROR"); - shutdown(remoteVars.clientsock, SHUT_RDWR); - close(remoteVars.clientsock); - return; - } - ready+=chunk; + EPHYR_DBG("READ COOKIE ERROR"); + close_client_sockets(); + return; } + ready+=chunk; } - } - else + +/* if(remoteVars.serverType == UDPFRAMES) { ready = recvfrom(remoteVars.serversock, msg, length, MSG_WAITALL, (struct sockaddr *) &remoteVars.address, &remoteVars.addrlen); EPHYR_DBG ("Connection from (%s)...\n", inet_ntoa (remoteVars.address.sin_addr)); @@ -3248,15 +3095,14 @@ void serverAcceptNotify(int fd, int ready_sock, void *data) EPHYR_DBG("Connected to client UDP socket..."); } } - +*/ if(strlen(remoteVars.cookie)) { EPHYR_DBG("got %d COOKIE BYTES from client", ready); if(strncmp(msg,remoteVars.cookie,32)) { EPHYR_DBG("Wrong cookie"); - shutdown(remoteVars.clientsock, SHUT_RDWR); - close(remoteVars.clientsock); + close_client_sockets(); return; } EPHYR_DBG("Cookie approved"); @@ -3268,12 +3114,11 @@ void serverAcceptNotify(int fd, int ready_sock, void *data) pthread_mutex_lock(&remoteVars.sendqueue_mutex); #if XORG_VERSION_CURRENT >= 11900000 - EPHYR_DBG("Set notify FD for client sock: %d",remoteVars.clientsock); - SetNotifyFd(remoteVars.clientsock, clientReadNotify, X_NOTIFY_READ, NULL); - #endif /* XORG_VERSION_CURRENT */ + EPHYR_DBG("Set notify FD for client sock: %d",remoteVars.clientsock_tcp); + SetNotifyFd(remoteVars.clientsock_tcp, clientReadNotify, X_NOTIFY_READ, NULL); + #endif // XORG_VERSION_CURRENT remoteVars.client_connected=TRUE; remoteVars.server_version_sent=FALSE; - remoteVars.clientEventSeq=0-1; set_client_version(0,0); if(remoteVars.checkConnectionTimer) { @@ -3302,48 +3147,27 @@ void serverAcceptNotify(int fd, int ready_sock, void *data) void close_server_socket(void) { #if XORG_VERSION_CURRENT >= 11900000 - EPHYR_DBG("Remove notify FD for server sock %d",remoteVars.serversock); - RemoveNotifyFd(remoteVars.serversock); + EPHYR_DBG("Remove notify FD for server sock %d",remoteVars.serversock_tcp); + RemoveNotifyFd(remoteVars.serversock_tcp); #endif /* XORG_VERSION_CURRENT */ - shutdown(remoteVars.serversock, SHUT_RDWR); - close(remoteVars.serversock); - remoteVars.serversock=-1; + shutdown(remoteVars.serversock_tcp, SHUT_RDWR); + close(remoteVars.serversock_tcp); + remoteVars.serversock_tcp=-1; } - -void open_socket(void) +void +open_udp_socket(void) { - const int y = 1; - - if(remoteVars.serverType==TCP) - { - EPHYR_DBG("Openning TCP socket..."); - remoteVars.serversock=socket (AF_INET, SOCK_STREAM, 0); - setsockopt( remoteVars.serversock, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); - remoteVars.address.sin_family = AF_INET; - } - else - { - EPHYR_DBG("Openning UDP socket..."); - remoteVars.serversock=socket (AF_INET, SOCK_DGRAM, 0); - remoteVars.address.sin_family = AF_UNSPEC; - } +/* const int y = 1; + EPHYR_DBG("Openning UDP socket..."); + remoteVars.serversock=socket (AF_INET, SOCK_DGRAM, 0); + remoteVars.address.sin_family = AF_UNSPEC; remoteVars.address.sin_addr.s_addr = INADDR_ANY; if(! strlen(remoteVars.acceptAddr)) EPHYR_DBG("Accepting connections from 0.0.0.0"); else EPHYR_DBG("Accepting connections from %s", remoteVars.acceptAddr); - if(!remoteVars.listenPort) - { - EPHYR_DBG("Listen on port %d", DEFAULT_PORT); - remoteVars.address.sin_port = htons (DEFAULT_PORT); - } - else - { - EPHYR_DBG("Listen on port %d", remoteVars.listenPort); - remoteVars.address.sin_port = htons (remoteVars.listenPort); - } if(!remoteVars.udpPort) { EPHYR_DBG("UDP port %d", DEFAULT_PORT+1); @@ -3358,22 +3182,64 @@ void open_socket(void) (struct sockaddr *) &remoteVars.address, sizeof (remoteVars.address)) != 0) { - EPHYR_DBG( "PORT IN USE!\n"); + EPHYR_DBG( "UDP PORT IN USE!\n"); terminateServer(-1); } listen (remoteVars.serversock, 1); remoteVars.addrlen = sizeof (struct sockaddr_in); +#if XORG_VERSION_CURRENT >= 11900000 + EPHYR_DBG("Set notify FD for server sock: %d",remoteVars.serversock); + EPHYR_DBG ("waiting for Client connection\n"); + SetNotifyFd(remoteVars.serversock, serverAcceptNotifyUDP, X_NOTIFY_READ, NULL); +#endif // XORG_VERSION_CURRENT + EPHYR_DBG("Server UDP socket is ready");*/ +} + +void open_socket(void) +{ + const int y = 1; + + EPHYR_DBG("Openning TCP socket..."); + remoteVars.send_frames_over_udp=FALSE; + remoteVars.serversock_tcp=socket (AF_INET, SOCK_STREAM, 0); + setsockopt( remoteVars.serversock_tcp, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); + remoteVars.tcp_address.sin_family = AF_INET; + remoteVars.tcp_address.sin_addr.s_addr = INADDR_ANY; + + if(! strlen(remoteVars.acceptAddr)) + EPHYR_DBG("Accepting connections from 0.0.0.0"); + else + EPHYR_DBG("Accepting connections from %s", remoteVars.acceptAddr); + if(!remoteVars.listenPort) + { + EPHYR_DBG("Listen on port %d", DEFAULT_PORT); + remoteVars.tcp_address.sin_port = htons (DEFAULT_PORT); + } + else + { + EPHYR_DBG("Listen on port %d", remoteVars.listenPort); + remoteVars.tcp_address.sin_port = htons (remoteVars.listenPort); + } + if (bind ( remoteVars.serversock_tcp, + (struct sockaddr *) &remoteVars.tcp_address, + sizeof (remoteVars.tcp_address)) != 0) + { + EPHYR_DBG( "TCP PORT IN USE!\n"); + terminateServer(-1); + } + listen (remoteVars.serversock_tcp, 1); + remoteVars.tcp_addrlen = sizeof (struct sockaddr_in); remoteVars.checkConnectionTimer=TimerSet(0,0,ACCEPT_TIMEOUT, checkSocketConnection, NULL); #if XORG_VERSION_CURRENT >= 11900000 - EPHYR_DBG("Set notify FD for server sock: %d",remoteVars.serversock); + EPHYR_DBG("Set notify FD for server sock: %d",remoteVars.serversock_tcp); EPHYR_DBG ("waiting for Client connection\n"); - SetNotifyFd(remoteVars.serversock, serverAcceptNotify, X_NOTIFY_READ, NULL); -#endif /* XORG_VERSION_CURRENT */ + SetNotifyFd(remoteVars.serversock_tcp, serverAcceptNotify, X_NOTIFY_READ, NULL); +#endif // XORG_VERSION_CURRENT - EPHYR_DBG("Server socket is ready"); + EPHYR_DBG("Server TCP socket is ready"); } @@ -3404,8 +3270,6 @@ void terminateServer(int exitStatus) pthread_mutex_destroy(&remoteVars.mainimg_mutex); pthread_mutex_destroy(&remoteVars.sendqueue_mutex); - pthread_mutex_destroy(&remoteVars.server_dgram_mutex); - pthread_mutex_destroy(&remoteVars.client_dgram_mutex); pthread_cond_destroy(&remoteVars.have_sendqueue_cond); if(remoteVars.main_img) @@ -3571,7 +3435,7 @@ remote_init(void) fclose(stdout); fclose(stdin); - remoteVars.serversock=-1; + remoteVars.serversock_tcp=remoteVars.sock_udp=-1; if(!remoteVars.initialJpegQuality) remoteVars.initialJpegQuality=remoteVars.jpegQuality=JPG_QUALITY; @@ -3579,8 +3443,6 @@ remote_init(void) remoteVars.compression=DEFAULT_COMPRESSION; remoteVars.selstruct.selectionMode = CLIP_BOTH; -#warning change this defaults values - remoteVars.serverType=UDP; if(!strlen(remote_get_init_geometry())) { @@ -3590,8 +3452,6 @@ remote_init(void) pthread_mutex_init(&remoteVars.mainimg_mutex, NULL); pthread_mutex_init(&remoteVars.sendqueue_mutex,NULL); - pthread_mutex_init(&remoteVars.server_dgram_mutex,NULL); - pthread_mutex_init(&remoteVars.client_dgram_mutex,NULL); pthread_cond_init(&remoteVars.have_sendqueue_cond,NULL); displayVar=secure_getenv("DISPLAY"); @@ -4992,7 +4852,7 @@ remote_paint_rect(KdScreenInfo *screen, // EPHYR_DBG("new update rect dimensions: %dx%d", width, height); // } -#warning debug block +/*#warning debug block currentRegion=regions; // int i=0; while(currentRegion) @@ -5006,7 +4866,7 @@ remote_paint_rect(KdScreenInfo *screen, totalSizeOfRegions=0; numOfRegs=0; -//end of debug block +//end of debug block*/ while(!allUnited) { @@ -5324,8 +5184,6 @@ int send_packet_as_datagrams(unsigned char* data, uint32_t length, uint8_t dgTyp unsigned char* dgram; uint32_t checksum; int writeRes; - uint16_t syncPackSeq=0; - pthread_mutex_lock(&remoteVars.server_dgram_mutex); dgInPack=length/(UDPDGRAMSIZE-SRVDGRAMHEADERSIZE); if(length%(UDPDGRAMSIZE-SRVDGRAMHEADERSIZE)) @@ -5335,19 +5193,12 @@ int send_packet_as_datagrams(unsigned char* data, uint32_t length, uint8_t dgTyp //setting sequence number switch(dgType) { - case ServerControlPacket: - seqNumber=&remoteVars.controlPacketSeq; - break; case ServerFramePacket: seqNumber=&remoteVars.framePacketSeq; break; case ServerRepaintPacket: seqNumber=&remoteVars.repaintPacketSeq; break; - default: - //always 0 for sync packets - seqNumber=&syncPackSeq; - break; } // EPHYR_DBG("Seq number: %d", *seqNumber); while(sent_bytes<length) @@ -5373,193 +5224,17 @@ int send_packet_as_datagrams(unsigned char* data, uint32_t length, uint8_t dgTyp checksum=crc32(checksum,dgram,dgram_length); //setting checksum *((uint32_t*)dgram)=checksum; - writeRes=write(remoteVars.clientsock, dgram, dgram_length); + writeRes=write(remoteVars.sock_udp, dgram, dgram_length); if(writeRes!=(int)dgram_length) { // EPHYR_DBG("Warning, sending packet failed. Sent %d bytes instead of %d",writeRes,dgram_length); } sent_bytes+=(dgram_length-SRVDGRAMHEADERSIZE); - switch(dgType) - { - case ServerControlPacket: - { - //add dgram to list - add_dgram_to_list(dgram, dgram_length, &remoteVars.server_control_datagrams); - break; - } - default: - free(dgram); - } + free(dgram); } (*seqNumber)++; - pthread_mutex_unlock(&remoteVars.server_dgram_mutex); return sent_bytes; } -//add dgram to list -void -add_dgram_to_list(unsigned char* dgram, uint16_t length, struct dgram_element** dg_list) -{ - //dgram mutex is locked on this point - struct dgram_element* dg=malloc(sizeof(struct dgram_element)); - struct dgram_element* current; - dg->length=length; - dg->data=dgram; - dg->next=NULL; - if(*dg_list) - { - current=*dg_list; - while(current->next) - { - current=current->next; - } - current->next=dg; - } - else - { - *dg_list=dg; - } -} - -//remove datagrams from list -// if !remove_all, stop after removing packet with seq==last_pack_seq -void -remove_dgram_from_list(struct dgram_element** dg_list, uint16_t last_pack_seq, BOOL remove_all) -{ - - //dgram mutex should be locked on this point!!! - struct dgram_element *current, *next, *prev=NULL; - uint16_t current_seq; - int32_t current_seq_long; - int32_t last_pack_seq_long; - - current=*dg_list; - while(current) - { - current_seq= *((uint16_t*)(current->data)+2); - current_seq_long=current_seq; - last_pack_seq_long=last_pack_seq; - //this is for the case when the seq is going over the max of the uint16 - if(abs(current_seq_long-last_pack_seq_long)>64535 && (current_seq_long<1000) ) - { - current_seq_long+=65536; - } - if(abs(current_seq_long-last_pack_seq_long)>64535 && (last_pack_seq_long<1000) ) - { - last_pack_seq_long+=65536; - } - - if(remove_all || (current_seq_long <= last_pack_seq_long)) - { - next=current->next; - if(prev) - prev->next=next; - if(*dg_list==current) - *dg_list=next; - free(current->data); - free(current); - current=next; - } - else - { - prev=current; - current=current->next; - } - } -} - -void -resend_dgram(uint8_t dgType, uint16_t packSeq, uint16_t dgSeq) -{ - uint16_t dgram_length; - unsigned char* dgram=NULL; - int write_res; - struct dgram_element *list, *cur; - switch (dgType) - { - case ServerControlPacket: - list=remoteVars.server_control_datagrams; - break; - default: - EPHYR_DBG("Requested resending dgram of unsupported type %d", dgType); - send_sync_failed_notification(); - return; - } - pthread_mutex_lock(&remoteVars.server_dgram_mutex); - cur=list; - while(cur) - { - if((*((uint16_t*)cur->data+2)==packSeq) && (*((uint16_t*)cur->data+4)==dgSeq)) - { - break; - } - cur=cur->next; - } - if(!cur) - { - EPHYR_DBG("WARNING! requested datagram of type %d with packet sequense %d and dg sequence %d not found in list", dgType, packSeq, dgSeq); - } - else - { - dgram_length=cur->length; - dgram=malloc(cur->length); - memcpy(dgram, cur->data, dgram_length); - } - pthread_mutex_unlock(&remoteVars.server_dgram_mutex); - if(!dgram) - { - send_sync_failed_notification(); - return; - } - write_res=write(remoteVars.clientsock, dgram, dgram_length); - if(write_res!=(int)dgram_length) - { - EPHYR_DBG("Warning, sending packet failed. Sent %d bytes instead of %d",write_res,dgram_length); - } - free(dgram); -} - -void -resend_dgram_packet(uint8_t dgType, uint16_t packSeq) -{ - uint16_t dg_in_pack=0; - uint16_t i; - struct dgram_element *list, *cur; - switch (dgType) - { - case ServerControlPacket: - list=remoteVars.server_control_datagrams; - break; - default: - EPHYR_DBG("Requested resending dgram of unsupported type %d", dgType); - send_sync_failed_notification(); - return; - } - pthread_mutex_lock(&remoteVars.server_dgram_mutex); - cur=list; - while(cur) - { - if(*((uint16_t*)cur->data+2)==packSeq) - { - break; - } - cur=cur->next; - } - if(!cur) - { - EPHYR_DBG("WARNING! requested packet of type %d with packet sequense %d not found in list", dgType, packSeq); - pthread_mutex_unlock(&remoteVars.server_dgram_mutex); - send_sync_failed_notification(); - return; - } - else - { - dg_in_pack=*((uint16_t*)cur->data+3); - } - pthread_mutex_unlock(&remoteVars.server_dgram_mutex); - EPHYR_DBG("resending packet of type %d with sequence %d and number of packets %d", dgType, packSeq, dg_in_pack); - for(i=0;i<dg_in_pack;++i) - resend_dgram(dgType, packSeq, i); -} unsigned int checkClientAlive(OsTimerPtr timer, CARD32 time_card, void* args) @@ -5584,18 +5259,7 @@ unsigned int sendServerAlive(OsTimerPtr timer, CARD32 time_card, void* args) _X_UNUSED int l; *((uint32_t*)buffer)=SRVKEEPALIVE; //4B - if(remoteVars.serverType==TCP) - { - l=write(remoteVars.clientsock,buffer,56); - } - else - { - //send also synchronization data - pthread_mutex_lock(&remoteVars.client_dgram_mutex); - *((uint16_t*)buffer+2)=remoteVars.clientEventSeq; - pthread_mutex_unlock(&remoteVars.client_dgram_mutex); - l=send_packet_as_datagrams(buffer, 6, ServerSyncPacket); - } + l=write(remoteVars.clientsock_tcp,buffer,56); return SERVERALIVE_TIMEOUT; } @@ -5608,28 +5272,7 @@ send_srv_disconnect(void) if(remoteVars.client_version<3) return; *((uint32_t*)buffer)=SRVDISCONNECT; //4B - if(remoteVars.serverType==TCP) - { - l=write(remoteVars.clientsock,buffer,56); - } - else - { - l=send_packet_as_datagrams(buffer, 4, ServerSyncPacket); - } -} - -void -send_sync_failed_notification(void) -{ - unsigned char buffer[56] = {0}; - //only using with UDP connections - if(remoteVars.serverType==TCP) - { - return; - } - - *((uint32_t*)buffer)=SRVSYNCFAILED; //4B - send_packet_as_datagrams(buffer, 4, ServerControlPacket); + l=write(remoteVars.clientsock_tcp,buffer,56); } void @@ -5641,270 +5284,7 @@ clean_everything(void) freeCursors(); clear_output_selection(); delete_all_windows(); - pthread_mutex_lock(&remoteVars.server_dgram_mutex); - remove_dgram_from_list(&remoteVars.server_control_datagrams, 0, TRUE); - remoteVars.framePacketSeq=remoteVars.controlPacketSeq=remoteVars.repaintPacketSeq=0; - pthread_mutex_unlock(&remoteVars.server_dgram_mutex); - pthread_mutex_lock(&remoteVars.client_dgram_mutex); - remove_dgram_from_list(&remoteVars.client_event_datagrams, 0, TRUE); - remove_resend_request(0, TRUE); - remoteVars.clientEventSeq=0-1; - pthread_mutex_unlock(&remoteVars.client_dgram_mutex); -} - -struct dgram_element* find_dgram_in_list(struct dgram_element** dg_list, uint16_t pack_seq) -{ - //dgram mutex should be locked on this point!!! - struct dgram_element *current; - uint16_t current_seq; - current=*dg_list; - while(current) - { - current_seq= *((uint16_t*)(current->data)+2); - if(current_seq==pack_seq) - break; - current=current->next; - } - return current; -} - -void -remote_check_event_packet_integrity(uint16_t seq_to_process) -{ - struct dgram_element* dgram; - unsigned char* dgram_data; - uint16_t current_seq; - uint16_t dgram_length; - struct timeval tv; - time_t curmsec; - BOOL have_missing=FALSE; - uint16_t *packets_process, *packets_missing; - int process_len=0, missing_len=0, i; - int max_len; - struct dgram_request_element *req; - unsigned char buffer[6];//4B EVENT and 2B missing seq; - - gettimeofday(&tv, NULL); - curmsec=tv.tv_sec*1000+tv.tv_usec/1000; - - pthread_mutex_lock(&remoteVars.client_dgram_mutex); - current_seq=remoteVars.clientEventSeq+1; - //went over max of uint16_t - if(current_seq>seq_to_process) - max_len=((int)seq_to_process+65536)-current_seq+1; - else - max_len=seq_to_process-current_seq+1; - packets_process=malloc(sizeof(uint16_t)*max_len); - packets_missing=malloc(sizeof(uint16_t)*max_len); - - while(1) - { - dgram=find_dgram_in_list(&remoteVars.client_event_datagrams, current_seq); - if(!dgram) - { - have_missing=TRUE; - req=find_resend_request(current_seq); - if(!req) - { - //create new request - req=malloc(sizeof(struct dgram_request_element)); - req->next=NULL; - req->seq=current_seq; - req->msec=curmsec; - if(remoteVars.cl_event_resend_request_last) - { - remoteVars.cl_event_resend_request_last->next=req; - } - remoteVars.cl_event_resend_request_last=req; - if(!remoteVars.cl_event_resend_request_first) - { - remoteVars.cl_event_resend_request_first=req; - } - packets_missing[missing_len++]=current_seq; - EPHYR_DBG("Missing event datagram %d",current_seq); - } - else - { - //already requested this dgram; - if(curmsec > req->msec + 200) - {//200 msec ellapsed since we requested it, requesting again - packets_missing[missing_len++]=current_seq; - req->msec=curmsec; - EPHYR_DBG("Still missing event datagram %d, requesting again",current_seq); - } - } - } - else - { - if(!have_missing) - { - //till now all packets are ok - remoteVars.clientEventSeq=packets_process[process_len++]=current_seq; - } - } - if(current_seq==seq_to_process) - break; - ++current_seq; - } - pthread_mutex_unlock(&remoteVars.client_dgram_mutex); - - //process events - for(i=0;i<process_len;++i) - { - pthread_mutex_lock(&remoteVars.client_dgram_mutex); - dgram_data=NULL; - - dgram=find_dgram_in_list(&remoteVars.client_event_datagrams, packets_process[i]); - if(dgram) - { - dgram_data=malloc(dgram->length); - dgram_length=dgram->length; - memcpy(dgram_data, dgram->data, dgram->length); - } - remove_dgram_from_list(&remoteVars.client_event_datagrams, packets_process[i], FALSE); - pthread_mutex_unlock(&remoteVars.client_dgram_mutex); - if(dgram_data) - { - remote_process_client_event((char*)dgram_data+CLDGRAMHEADERSIZE, dgram_length-CLDGRAMHEADERSIZE); - free(dgram_data); - } - } - - *((uint32_t*)buffer)=RESENDEVENTS; //4B - //request resend missing events - for(i=0;i<missing_len;++i) - { - *((uint16_t*)buffer+2)=packets_missing[i]; - send_packet_as_datagrams(buffer, 6, ServerSyncPacket); - } - free(packets_missing); - free(packets_process); -} - -void -remote_recv_dgram(void) -{ - char buffer[UDPDGRAMSIZE]; - uint32_t crc, checksum; - uint16_t seq; - uint8_t dgType; - int32_t current_long; - int32_t last_long; - unsigned char* dgram; - - - int length=read(remoteVars.clientsock,buffer, UDPDGRAMSIZE); -// EPHYR_DBG("Read datagram with size %d",length); - if(length<=CLDGRAMHEADERSIZE) - { -// EPHYR_DBG("Error reading datagram, the size is smaller than a header size: %d", length); - return; - } - checksum=*((uint32_t*)buffer); - memset(buffer, 0, 4); - crc=crc32(0L, Z_NULL, 0); - crc=crc32(crc,(unsigned char*)buffer,length); - if(crc!=checksum) - { - EPHYR_DBG("checksum failed %d instead of %d",crc,checksum); - return; - } - seq=*((uint16_t*)buffer+2); - dgType=*((uint8_t*)buffer+6); - - switch(dgType) - { - case ClientEventPacket: -// EPHYR_DBG("Client event DG %d",seq); - break; - default: - //Sync packets should be procesed immeidately - remote_process_client_event(buffer+CLDGRAMHEADERSIZE, length-CLDGRAMHEADERSIZE); - return; - } - current_long=seq; - pthread_mutex_lock(&remoteVars.client_dgram_mutex); - last_long=remoteVars.clientEventSeq; - if(abs(current_long-last_long)>64535 && (current_long<1000) ) - { - current_long+=65536; - } - - if(abs(current_long-last_long)>64535 && (last_long<1000) ) - { - last_long+=65536; - } - - if(current_long<=last_long) - { - EPHYR_DBG("Late client event sequence arrived: %d, last processed: %d", seq, remoteVars.clientEventSeq); - pthread_mutex_unlock(&remoteVars.client_dgram_mutex); - return; - } - dgram=malloc(length); - memcpy(dgram,buffer,length); - add_dgram_to_list(dgram, length, &remoteVars.client_event_datagrams); - //if it's resendet dgram, remove request - remove_resend_request(seq, FALSE); - pthread_mutex_unlock(&remoteVars.client_dgram_mutex); - remote_check_event_packet_integrity(seq); -} - -struct dgram_request_element* -find_resend_request(uint16_t seq) -{ - struct dgram_request_element* cur=remoteVars.cl_event_resend_request_first; - while(cur) - { - if(cur->seq==seq) - return cur; - cur=cur->next; - } - return NULL; -} - -void -remove_resend_request(uint16_t seq, BOOL all) -{ - struct dgram_request_element* cur=remoteVars.cl_event_resend_request_first; - struct dgram_request_element *next, *prev=NULL; - while(cur) - { - next=cur->next; - if(all) - { - free(cur); - } - else - { - if(cur->seq==seq) - { - if(prev) - { - prev->next=next; - } - if(cur==remoteVars.cl_event_resend_request_first) - { - remoteVars.cl_event_resend_request_first=next; - } - if(cur==remoteVars.cl_event_resend_request_last) - { - remoteVars.cl_event_resend_request_last=prev; - } - free(cur); - } - else - { - prev=cur; - } - - } - cur=next; - } - if(all) - { - remoteVars.cl_event_resend_request_first=remoteVars.cl_event_resend_request_last=NULL; - } + remoteVars.framePacketSeq=remoteVars.repaintPacketSeq=0; } void @@ -5916,7 +5296,7 @@ resend_frame(uint32_t crc) uint32_t size; struct cache_elem* frame=find_cache_element(crc); EPHYR_DBG("Client asks to resend frame from cash with crc %x",crc); - if(remoteVars.serverType==TCP) + if(remoteVars.send_frames_over_udp) return; pthread_mutex_lock(&remoteVars.sendqueue_mutex); if(! frame) @@ -5934,3 +5314,16 @@ resend_frame(uint32_t crc) free(data); send_packet_as_datagrams(packet,size+8,ServerFramePacket); } + +void +close_client_sockets(void) +{ + shutdown(remoteVars.clientsock_tcp, SHUT_RDWR); + close(remoteVars.clientsock_tcp); + if(remoteVars.send_frames_over_udp) + { + shutdown(remoteVars.sock_udp, SHUT_RDWR); + close(remoteVars.sock_udp); + remoteVars.send_frames_over_udp=FALSE; + } +} diff --git a/x2gokdriveremote.h b/x2gokdriveremote.h index ff57dab..aecd04f 100644 --- a/x2gokdriveremote.h +++ b/x2gokdriveremote.h @@ -111,8 +111,6 @@ //UDP Server DGRAM Header - 4B checksum + 2B packet seq number + 2B amount of datagrams + 2B datagram seq number + 1B type #define SRVDGRAMHEADERSIZE (4+2+2+2+1) -//UDP Client DGRAM Header - 4B checksum + 2B packet seq number + 1B type -#define CLDGRAMHEADERSIZE (4+2+1) //port to listen by default #define DEFAULT_PORT 15000 @@ -132,7 +130,8 @@ //always 4 #define XSERVERBPP 4 -enum msg_type{FRAME,DELETED, CURSOR, DELETEDCURSOR, SELECTION, SERVERVERSION, DEMANDCLIENTSELECTION, REINIT, WINUPDATE, SRVKEEPALIVE, SRVDISCONNECT, SRVSYNCFAILED, RESENDEVENTS, CACHEFRAME}; +enum msg_type{FRAME,DELETED, CURSOR, DELETEDCURSOR, SELECTION, SERVERVERSION, DEMANDCLIENTSELECTION, REINIT, WINUPDATE, + SRVKEEPALIVE, SRVDISCONNECT, CACHEFRAME, UDPOPEN, UDPFAILED}; enum AgentState{STARTING, RUNNING, RESUMING, SUSPENDING, SUSPENDED, TERMINATING, TERMINATED}; enum Compressions{JPEG,PNG}; enum SelectionType{PRIMARY,CLIPBOARD}; @@ -147,21 +146,12 @@ enum WinType{WINDOW_TYPE_DESKTOP, WINDOW_TYPE_DOCK, WINDOW_TYPE_TOOLBAR, WINDOW_ //new state requested by WINCHANGE event enum WinState{WIN_UNCHANGED, WIN_DELETED, WIN_ICONIFIED}; -//which type of server socket to use -enum ServerType{TCP, UDP}; - //UDP datagrams types enum ServerDgramTypes{ ServerFramePacket, //dgram belongs to packet representing frame - ServerControlPacket, //dgram belongs to packet which couldn't be missed, but doesn't need to be processed in the real time ServerRepaintPacket, // dgram belongs to packet with screen repaint and the loss can be ignored - ServerSyncPacket //dgram belongs to packet with sync request }; -enum ClientDgramType{ - ClientEventPacket, //Event packet, high priority - ClientSyncPacket //Packet with synchronization data -}; //Size of 1 window update (new or changed window) = 4xwinId + type of update + 7 coordinates + visibility + type of window + size of name buffer + icon_size #define WINUPDSIZE 4*sizeof(uint32_t) + sizeof(int8_t) + 7*sizeof(int16_t) + sizeof(int8_t) + sizeof(int8_t) + sizeof(int16_t) + sizeof(int32_t) @@ -193,14 +183,12 @@ enum ClientDgramType{ #define KEEPALIVE 12 #define CACHEREBUILD 13 #define WINCHANGE 14 -//resend missing server control dgrams -#define RESENDSCONTROL 15 //client is going to disconnect -#define DISCONNECTCLIENT 16 -//synchronization with client has failed -#define CLIENTSYNCFAILED 17 +#define DISCONNECTCLIENT 15 //ask to resend particular frame -#define RESENDFRAME 18 +#define RESENDFRAME 16 +//client is requesting UDP port for frames +#define OPENUDP 17 #define EVLENGTH 41 @@ -268,14 +256,6 @@ struct dgram_element struct dgram_element* next; }; -//resend void request_selection_from_client(enum SelectionType selection) -struct dgram_request_element -{ - uint16_t seq; - time_t msec; - struct dgram_request_element* next; -}; - //we can find out cursor type by analyzing size of data. @@ -480,16 +460,14 @@ struct _remoteHostVars unsigned long send_thread_id; - enum ServerType serverType; uint16_t framePacketSeq; - uint16_t controlPacketSeq; uint16_t repaintPacketSeq; - uint16_t clientEventSeq; //client information enum OS_VERSION client_os; uint16_t client_version; BOOL server_version_sent; + BOOL send_frames_over_udp; //for control uint32_t cache_elements; @@ -507,7 +485,7 @@ struct _remoteHostVars uint64_t sizeOfRects; uint64_t sizeOfRegions;*/ - int clientsock, serversock; + int clientsock_tcp, serversock_tcp, sock_udp; BOOL rootless; //array of screen regions @@ -540,23 +518,15 @@ struct _remoteHostVars struct sentCursor* sentCursorsHead; struct sentCursor* sentCursorsTail; - struct dgram_element* server_control_datagrams; - struct dgram_element* client_event_datagrams; - struct dgram_request_element *cl_event_resend_request_first, *cl_event_resend_request_last; - struct remoteWindow* windowList; BOOL windowsUpdated; pthread_mutex_t sendqueue_mutex; - //mutex for server dgrams_synchronization - pthread_mutex_t server_dgram_mutex; - //mutex for client dgrams_synchronization - pthread_mutex_t client_dgram_mutex; pthread_mutex_t mainimg_mutex; pthread_cond_t have_sendqueue_cond; - socklen_t addrlen; - struct sockaddr_in address, udp_address; + socklen_t tcp_addrlen, udp_addrlen; + struct sockaddr_in tcp_address, udp_address; BOOL client_connected; BOOL client_initialized; @@ -573,7 +543,6 @@ int send_selection_chunk(int sel, unsigned char* data, uint32_t length, uint32_t int send_output_selection(struct OutputChunk* chunk); int send_packet_as_datagrams(unsigned char* data, uint32_t length, uint8_t dgType); -void resend_dgrams(char* buffer, int length, uint8_t dgType); void set_client_version(uint16_t ver, uint16_t os); @@ -595,8 +564,11 @@ unsigned int checkSocketConnection(OsTimerPtr timer, CARD32 time, void* args); void restartTimerOnInit(void); void open_socket(void); +void open_udp_socket(void); void close_server_socket(void); +void close_client_sockets(void); + void setAgentState(int state); void terminateServer(int exitStatus); @@ -660,7 +632,6 @@ const char* remote_get_init_geometry(void); void remote_check_windowstree(WindowPtr root); void remote_check_window(WindowPtr win); BOOL remote_process_client_event(char* buff, int length); -void remote_recv_dgram(void); struct remoteWindow* remote_find_window(WindowPtr win); WindowPtr remote_find_window_on_screen(WindowPtr win, WindowPtr root); WindowPtr remote_find_window_on_screen_by_id(uint32_t winId, WindowPtr root); @@ -673,22 +644,13 @@ void remote_check_rootless_windows_for_updates(KdScreenInfo *screen); void markDirtyRegions(uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint8_t jpegQuality, uint32_t winId); int getDirtyScreenRegion(void); void send_dirty_region(int index); -void add_dgram_to_list(unsigned char* dgram, uint16_t length, struct dgram_element** dg_list); -void remove_dgram_from_list(struct dgram_element** dg_list, uint16_t last_pack_seq, BOOL remove_all); -void resend_dgram(uint8_t dgType, uint16_t packSeq, uint16_t dgSeq); -void resend_dgram_packet(uint8_t dgType, uint16_t packSeq); unsigned int checkClientAlive(OsTimerPtr timer, CARD32 time_card, void* args); unsigned int sendServerAlive(OsTimerPtr timer, CARD32 time_card, void* args); void send_srv_disconnect(void); BOOL insideOfRegion(struct PaintRectRegion* reg, int x , int y); struct PaintRectRegion* findRegionForPoint(struct PaintRectRegion* firstRegion, int x , int y); BOOL unitePaintRegions(struct PaintRectRegion* firstRegion); -void send_sync_failed_notification(void); //perform cleanup of all caches and queues when disconnecting or performing reinitialization void clean_everything(void); -void remote_check_event_packet_integrity(uint16_t seq_to_process); -struct dgram_element* find_dgram_in_list(struct dgram_element** dg_list, uint16_t pack_seq); -struct dgram_request_element* find_resend_request(uint16_t seq); -void remove_resend_request(uint16_t seq, BOOL all); void resend_frame(uint32_t crc); #endif /* X2GOKDRIVE_REMOTE_H */ -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gokdrive.git