diff --git a/xup/xup.c b/xup/xup.c index 8ddc079f..8e28e7ab 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -20,6 +20,7 @@ #include "xup.h" #include "log.h" +#include "trans.h" #define LOG_LEVEL 1 #define LLOG(_level, _args) \ @@ -27,98 +28,14 @@ #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) -/******************************************************************************/ -/* returns error */ -int DEFAULT_CC -lib_recv(struct mod *mod, char *data, int len) -{ - int rcvd; - - if (mod->sck_closed) - { - return 1; - } - - while (len > 0) - { - rcvd = g_tcp_recv(mod->sck, data, len, 0); - - if (rcvd == -1) - { - if (g_tcp_last_error_would_block(mod->sck)) - { - if (mod->server_is_term(mod)) - { - return 1; - } - - g_tcp_can_recv(mod->sck, 10); - } - else - { - return 1; - } - } - else if (rcvd == 0) - { - mod->sck_closed = 1; - return 1; - } - else - { - data += rcvd; - len -= rcvd; - } - } - - return 0; -} +static int APP_CC +lib_mod_process_message(struct mod *mod, struct stream *s); -/*****************************************************************************/ -/* returns error */ -int DEFAULT_CC -lib_send(struct mod *mod, char *data, int len) +/******************************************************************************/ +static int APP_CC +lib_send_copy(struct mod *mod, struct stream *s) { - int sent; - - if (mod->sck_closed) - { - return 1; - } - - while (len > 0) - { - sent = g_tcp_send(mod->sck, data, len, 0); - - if (sent == -1) - { - if (g_tcp_last_error_would_block(mod->sck)) - { - if (mod->server_is_term(mod)) - { - return 1; - } - - g_tcp_can_send(mod->sck, 10); - } - else - { - return 1; - } - } - else if (sent == 0) - { - mod->sck_closed = 1; - return 1; - } - else - { - data += sent; - len -= sent; - } - } - - return 0; + return trans_write_copy_s(mod->trans, s); } /******************************************************************************/ @@ -144,7 +61,7 @@ lib_mod_log_peer(struct mod *mod) int gid; my_pid = g_getpid(); - if (g_sck_get_peer_cred(mod->sck, &pid, &uid, &gid) == 0) + if (g_sck_get_peer_cred(mod->trans->sck, &pid, &uid, &gid) == 0) { log_message(LOG_LEVEL_INFO, "lib_mod_log_peer: xrdp_pid=%d connected " "to X11rdp_pid=%d X11rdp_uid=%d X11rdp_gid=%d " @@ -161,6 +78,57 @@ lib_mod_log_peer(struct mod *mod) return 0; } +/******************************************************************************/ +static int APP_CC +lib_data_in(struct trans *trans) +{ + struct mod *self; + struct stream *s; + int len; + + if (trans == 0) + { + return 1; + } + + self = (struct mod *)(trans->callback_data); + s = trans_get_in_s(trans); + + if (s == 0) + { + return 1; + } + + switch (trans->extra_flags) + { + case 1: + s->p = s->data; + in_uint8s(s, 4); /* processed later in lib_mod_process_message */ + in_uint32_le(s, len); + if (len < 0 || len > 128 * 1024) + { + g_writeln("lib_data_in: bad size"); + return 1; + } + trans->header_size = len + 8; + trans->extra_flags = 2; + break; + case 2: + s->p = s->data; + if (lib_mod_process_message(self, s) != 0) + { + g_writeln("lib_data_in: lib_mod_process_message failed"); + return 1; + } + init_stream(s, 0); + trans->header_size = 8; + trans->extra_flags = 1; + break; + } + + return 0; +} + /******************************************************************************/ /* return error */ int DEFAULT_CC @@ -169,7 +137,6 @@ lib_mod_connect(struct mod *mod) int error; int len; int i; - int index; int use_uds; struct stream *s; char con_port[256]; @@ -207,64 +174,34 @@ lib_mod_connect(struct mod *mod) mod->sck_closed = 0; i = 0; - while (1) + if (use_uds) { - if (use_uds) + mod->trans = trans_create(TRANS_MODE_UNIX, 8 * 8192, 8192); + if (mod->trans == 0) { - mod->sck = g_tcp_local_socket(); - if (mod->sck < 0) - { - free_stream(s); - return 1; - } + free_stream(s); + return 1; } - else + } + else + { + mod->trans = trans_create(TRANS_MODE_TCP, 8 * 8192, 8192); + if (mod->trans == 0) { - mod->sck = g_tcp_socket(); - if (mod->sck < 0) - { - free_stream(s); - return 1; - } - - g_tcp_set_non_blocking(mod->sck); - g_tcp_set_no_delay(mod->sck); + free_stream(s); + return 1; } + } - /* mod->server_msg(mod, "connecting...", 0); */ + while (1) + { - if (use_uds) - { - error = g_tcp_local_connect(mod->sck, con_port); - } - else - { - error = g_tcp_connect(mod->sck, mod->ip, con_port); - } + /* mod->server_msg(mod, "connecting...", 0); */ - if (error == -1) + error = -1; + if (trans_connect(mod->trans, mod->ip, con_port, 3000) == 0) { - if (g_tcp_last_error_would_block(mod->sck)) - { - error = 0; - index = 0; - - while (!g_tcp_can_send(mod->sck, 100)) - { - index++; - - if ((index >= 30) || mod->server_is_term(mod)) - { - mod->server_msg(mod, "connect timeout", 0); - error = 1; - break; - } - } - } - else - { - /* mod->server_msg(mod, "connect error", 0); */ - } + error = 0; } if (error == 0) @@ -272,8 +209,6 @@ lib_mod_connect(struct mod *mod) break; } - g_tcp_close(mod->sck); - mod->sck = 0; i++; if (i >= 60) @@ -308,7 +243,7 @@ lib_mod_connect(struct mod *mod) len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); } if (error == 0) @@ -326,7 +261,7 @@ lib_mod_connect(struct mod *mod) len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); } if (error == 0) @@ -348,13 +283,15 @@ lib_mod_connect(struct mod *mod) len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); } free_stream(s); if (error != 0) { + trans_delete(mod->trans); + mod->trans = 0; mod->server_msg(mod, "some problem", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; @@ -362,7 +299,11 @@ lib_mod_connect(struct mod *mod) else { mod->server_msg(mod, "connected ok", 0); - mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); + mod->trans->trans_data_in = lib_data_in; + mod->trans->header_size = 8; + mod->trans->callback_data = mod; + mod->trans->no_stream_init_on_data_in = 1; + mod->trans->extra_flags = 1; } LIB_DEBUG(mod, "out lib_mod_connect"); @@ -411,7 +352,7 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2, len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); } } @@ -434,7 +375,7 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2, len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - rv = lib_send(mod, s->data, len); + rv = lib_send_copy(mod, s); free_stream(s); LIB_DEBUG(mod, "out lib_mod_event"); return rv; @@ -1092,7 +1033,7 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy, len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); free_stream(s); return 0; } @@ -1100,7 +1041,7 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy, /******************************************************************************/ /* return error */ static int APP_CC -process_server_paint_rect_shmem(struct mod *mod, struct stream *s) +process_server_paint_rect_shmem(struct mod *amod, struct stream *s) { int rv; int x; @@ -1132,37 +1073,33 @@ process_server_paint_rect_shmem(struct mod *mod, struct stream *s) bmpdata = 0; rv = 0; - - if (flags == 0) /* screen */ + if (amod->screen_shmem_id_mapped == 0) { - if (mod->screen_shmem_id_mapped == 0) + amod->screen_shmem_id = shmem_id; + amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id); + if (amod->screen_shmem_pixels == (void*)-1) { - mod->screen_shmem_id = shmem_id; - mod->screen_shmem_pixels = g_shmat(mod->screen_shmem_id); - if (mod->screen_shmem_pixels == (void*)-1) - { - /* failed */ - mod->screen_shmem_id = 0; - mod->screen_shmem_pixels = 0; - mod->screen_shmem_id_mapped = 0; - } - else - { - mod->screen_shmem_id_mapped = 1; - } + /* failed */ + amod->screen_shmem_id = 0; + amod->screen_shmem_pixels = 0; + amod->screen_shmem_id_mapped = 0; } - if (mod->screen_shmem_pixels != 0) + else { - bmpdata = mod->screen_shmem_pixels + shmem_offset; + amod->screen_shmem_id_mapped = 1; } } + if (amod->screen_shmem_pixels != 0) + { + bmpdata = amod->screen_shmem_pixels + shmem_offset; + } if (bmpdata != 0) { - rv = mod->server_paint_rect(mod, x, y, cx, cy, - bmpdata, width, height, - srcx, srcy); + rv = amod->server_paint_rect(amod, x, y, cx, cy, + bmpdata, width, height, + srcx, srcy); } - send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id); + send_paint_rect_ack(amod, flags, x, y, cx, cy, frame_id); return rv; } @@ -1184,7 +1121,7 @@ send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id) len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); free_stream(s); return 0; } @@ -1421,17 +1358,16 @@ lib_send_client_info(struct mod *mod) len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); - lib_send(mod, s->data, len); + lib_send_copy(mod, s); free_stream(s); return 0; } /******************************************************************************/ /* return error */ -int DEFAULT_CC -lib_mod_signal(struct mod *mod) +static int APP_CC +lib_mod_process_message(struct mod *mod, struct stream *s) { - struct stream *s; int num_orders; int index; int rv; @@ -1439,11 +1375,7 @@ lib_mod_signal(struct mod *mod) int type; char *phold; - LIB_DEBUG(mod, "in lib_mod_signal"); - make_stream(s); - init_stream(s, 8192); - rv = lib_recv(mod, s->data, 8); - + rv = 0; if (rv == 0) { in_uint16_le(s, type); @@ -1452,72 +1384,54 @@ lib_mod_signal(struct mod *mod) if (type == 1) /* original order list */ { - init_stream(s, len); - rv = lib_recv(mod, s->data, len); - - if (rv == 0) + for (index = 0; index < num_orders; index++) { - for (index = 0; index < num_orders; index++) - { - in_uint16_le(s, type); - rv = lib_mod_process_orders(mod, type, s); + in_uint16_le(s, type); + rv = lib_mod_process_orders(mod, type, s); - if (rv != 0) - { - break; - } + if (rv != 0) + { + break; } } } else if (type == 2) /* caps */ { - g_writeln("lib_mod_signal: type 2 len %d", len); - init_stream(s, len); - rv = lib_recv(mod, s->data, len); - - if (rv == 0) + g_writeln("lib_mod_process_message: type 2 len %d", len); + for (index = 0; index < num_orders; index++) { - for (index = 0; index < num_orders; index++) + phold = s->p; + in_uint16_le(s, type); + in_uint16_le(s, len); + + switch (type) { - phold = s->p; - in_uint16_le(s, type); - in_uint16_le(s, len); - - switch (type) - { - default: - g_writeln("lib_mod_signal: unknown cap type %d len %d", - type, len); - break; - } - - s->p = phold + len; + default: + g_writeln("lib_mod_process_message: unknown cap type %d len %d", + type, len); + break; } - lib_send_client_info(mod); + s->p = phold + len; } + + lib_send_client_info(mod); } else if (type == 3) /* order list with len after type */ { - init_stream(s, len); - rv = lib_recv(mod, s->data, len); - - if (rv == 0) + for (index = 0; index < num_orders; index++) { - for (index = 0; index < num_orders; index++) - { - phold = s->p; - in_uint16_le(s, type); - in_uint16_le(s, len); - rv = lib_mod_process_orders(mod, type, s); - - if (rv != 0) - { - break; - } + phold = s->p; + in_uint16_le(s, type); + in_uint16_le(s, len); + rv = lib_mod_process_orders(mod, type, s); - s->p = phold + len; + if (rv != 0) + { + break; } + + s->p = phold + len; } } else @@ -1526,11 +1440,18 @@ lib_mod_signal(struct mod *mod) } } - free_stream(s); - LIB_DEBUG(mod, "out lib_mod_signal"); return rv; } +/******************************************************************************/ +/* return error */ +int DEFAULT_CC +lib_mod_signal(struct mod *mod) +{ + g_writeln("lib_mod_signal: not used"); + return 0; +} + /******************************************************************************/ /* return error */ int DEFAULT_CC @@ -1579,19 +1500,14 @@ int DEFAULT_CC lib_mod_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount, tbus *write_objs, int *wcount, int *timeout) { - int i; - - i = *rcount; - if (mod != 0) { - if (mod->sck_obj != 0) + if (mod->trans != 0) { - read_objs[i++] = mod->sck_obj; + trans_get_wait_objs_rw(mod->trans, read_objs, rcount, + write_objs, wcount); } } - - *rcount = i; return 0; } @@ -1603,15 +1519,11 @@ lib_mod_check_wait_objs(struct mod *mod) int rv; rv = 0; - if (mod != 0) { - if (mod->sck_obj != 0) + if (mod->trans != 0) { - if (g_is_wait_obj_set(mod->sck_obj)) - { - rv = lib_mod_signal(mod); - } + rv = trans_check_wait_objs(mod->trans); } } @@ -1658,9 +1570,7 @@ mod_exit(struct mod *mod) { return 0; } - - g_delete_wait_obj_from_socket(mod->sck_obj); - g_tcp_close(mod->sck); + trans_delete(mod->trans); g_free(mod); return 0; } diff --git a/xup/xup.h b/xup/xup.h index 3a569c7f..b7ec142c 100644 --- a/xup/xup.h +++ b/xup/xup.h @@ -162,4 +162,5 @@ struct mod int screen_shmem_id; int screen_shmem_id_mapped; /* boolean */ char *screen_shmem_pixels; + struct trans *trans; };