int APP_CC trans_connect(struct trans* self, const char* server, const char* port, int timeout) { int error; if (self->sck != 0) { g_tcp_close(self->sck); } self->sck = g_tcp_socket(); g_tcp_set_non_blocking(self->sck); error = g_tcp_connect(self->sck, server, port); if (error == -1) { if (g_tcp_last_error_would_block(self->sck)) { if (g_tcp_can_send(self->sck, timeout)) { self->status = 1; /* ok */ self->type1 = 3; /* client */ return 0; } } return 1; } self->status = 1; /* ok */ self->type1 = 3; /* client */ return 0; }
/* returns error */ int APP_CC xrdp_tcp_send(struct xrdp_tcp* self, struct stream* s) { int len; int total; int sent; struct xrdp_session* session; if (self->sck_closed) { DEBUG((" in xrdp_tcp_send, sck closed")); return 1; } len = s->end - s->data; DEBUG((" in xrdp_tcp_send, gota send %d bytes", len)); session = self->iso_layer->mcs_layer->sec_layer->rdp_layer->session; total = 0; while (total < len) { sent = g_tcp_send(self->sck, s->data + total, len - total, 0); if (sent == -1) { if (g_tcp_last_error_would_block(self->sck)) { if (!g_tcp_can_send(self->sck, 10)) { if (session->is_term != 0) { if (session->is_term()) { DEBUG((" out xrdp_tcp_send, terminated")); return 1; } } } } else { self->sck_closed = 1; DEBUG((" error = -1 in xrdp_tcp_send socket %d", self->sck)); return 1; } } else if (sent == 0) { self->sck_closed = 1; DEBUG((" error = 0 in xrdp_tcp_send socket %d", self->sck)); return 1; } else { #if defined(XRDP_DEBUG) g_hexdump(s->data + total, sent); #endif total = total + sent; } } DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len)); return 0; }
int APP_CC trans_force_write_s(struct trans *self, struct stream *out_s) { int size; int total; int sent; if (self->status != TRANS_STATUS_UP) { return 1; } size = (int) (out_s->end - out_s->data); total = 0; if (trans_send_waiting(self, 1) != 0) { self->status = TRANS_STATUS_DOWN; return 1; } while (total < size) { sent = self->trans_send(self, out_s->data + total, size - total); if (sent == -1) { if (g_tcp_last_error_would_block(self->sck)) { if (!g_tcp_can_send(self->sck, 100)) { /* check for term here */ if (self->is_term != 0) { if (self->is_term()) { /* term */ self->status = TRANS_STATUS_DOWN; return 1; } } } } else { /* error */ self->status = TRANS_STATUS_DOWN; return 1; } } else if (sent == 0) { /* error */ self->status = TRANS_STATUS_DOWN; return 1; } else { total = total + sent; } } return 0; }
int DEFAULT_CC xml_send_error(int client, const char* message) { xmlChar* xmlbuff; xmlDocPtr doc; xmlNodePtr node; struct stream* s; int buff_size, size; xmlChar* version; xmlChar* error; xmlChar* msg; version = xmlCharStrdup("1.0"); doc = xmlNewDoc(version); if (doc == NULL) { log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "sesman[xml_send_error]: " "Unable to create the document"); xmlFree(version); return 0; } error = xmlCharStrdup("error"); msg = xmlCharStrdup(message); doc->encoding = xmlCharStrdup("UTF-8"); node = xmlNewNode(NULL, error); xmlNodeSetContent(node, msg); xmlDocSetRootElement(doc, node); xmlDocDumpFormatMemory(doc, &xmlbuff, &buff_size, 1); log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "sesman[xml_send_error]: " "data send : %s",xmlbuff); make_stream(s); init_stream(s, buff_size + 6); out_uint32_be(s,buff_size); out_uint8p(s, xmlbuff, buff_size) size = s->p - s->data; if (g_tcp_can_send(client, 10)) { buff_size = g_tcp_send(client, s->data, size, 0); } else { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[xml_send_error]: " "Unable to send xml response: %s, cause: %s", xmlbuff, strerror(g_get_errno())); } free_stream(s); xmlFreeDoc(doc); xmlFree(xmlbuff); xmlFree(version); xmlFree(error); xmlFree(msg); return buff_size; }
int DEFAULT_CC xml_send_info(int client, xmlDocPtr doc) { xmlChar* xmlbuff; int buff_size, size; struct stream* s; xmlDocDumpFormatMemory(doc, &xmlbuff, &buff_size, 1); log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[xml_send_info]: " "data send : %s\n",xmlbuff); make_stream(s); init_stream(s, buff_size + 6); out_uint32_be(s,buff_size); out_uint8p(s, xmlbuff, buff_size) size = s->p - s->data; if (g_tcp_can_send(client, 10)) { int sended = 0; int send = 0; while(sended < size) { send = (size-sended) > 2048 ? 2048 : size-sended; sended += g_tcp_send(client, s->data+sended, send, 0); if (sended < size) { if (g_get_errno() != 0) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[xml_send_info]: " "Error while send %s\n",g_get_strerror()); goto end; } } } if (sended != size) { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[xml_send_info]: " "Error while sending data %i != %i\n",sended, size); } } else { log_message(&(g_cfg->log), LOG_LEVEL_DEBUG_PLUS, "sesman[xml_send_info]: " "Unable to send xml response: %s, cause: %s", xmlbuff, strerror(g_get_errno())); } end: free_stream(s); xmlFree(xmlbuff); return buff_size; }
/* returns error */ int APP_CC rdp_tcp_send(struct rdp_tcp *self, struct stream *s) { int len; int total; int sent; if (self->sck_closed) { DEBUG((" out rdp_tcp_send error sck closed")); return 1; } len = s->end - s->data; DEBUG((" in rdp_tcp_send gota send %d bytes on sck %d", len, self->sck)); total = 0; while (total < len) { sent = g_tcp_send(self->sck, s->data + total, len - total, 0); if (sent == -1) { if (g_tcp_last_error_would_block(self->sck)) { g_tcp_can_send(self->sck, 10); } else { self->sck_closed = 1; DEBUG((" out rdp_tcp_send error unknown")); return 1; } } else if (sent == 0) { self->sck_closed = 1; DEBUG((" out rdp_tcp_send error connection dropped")); return 1; } else { total = total + sent; } } return 0; }
int APP_CC trans_force_write(struct trans* self) { int size; int total; int rv; int sent; if (self->status != 1) { return 1; } rv = 0; size = (int)(self->out_s->end - self->out_s->data); total = 0; while (total < size) { sent = g_tcp_send(self->sck, self->out_s->data + total, size - total, 0); if (sent == -1) { if (g_tcp_last_error_would_block(self->sck)) { if (!g_tcp_can_send(self->sck, 10)) { /* check for term here */ } } else { /* error */ self->status = 0; rv = 1; } } else if (sent == 0) { /* error */ self->status = 0; rv = 1; } else { total = total + sent; } } return rv; }
/* returns error */ int DEFAULT_CC lib_send(struct mod *mod, char *data, int len) { 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; }
int APP_CC trans_connect(struct trans* self, const char* server, const char* port, int timeout) { int error; if (self->sck != 0) { g_tcp_close(self->sck); } if (self->mode == TRANS_MODE_TCP) /* tcp */ { self->sck = g_tcp_socket(); g_tcp_set_non_blocking(self->sck); error = g_tcp_connect(self->sck, server, port); } else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ { self->sck = g_tcp_local_socket(); g_tcp_set_non_blocking(self->sck); error = g_tcp_local_connect(self->sck, port); } else { self->status = TRANS_STATUS_DOWN; return 1; } if (error == -1) { if (g_tcp_last_error_would_block(self->sck)) { if (g_tcp_can_send(self->sck, timeout)) { self->status = TRANS_STATUS_UP; /* ok */ self->type1 = TRANS_TYPE_CLIENT; /* client */ return 0; } } return 1; } self->status = TRANS_STATUS_UP; /* ok */ self->type1 = TRANS_TYPE_CLIENT; /* client */ return 0; }
int APP_CC trans_connect(struct trans *self, const char *server, const char *port, int timeout) { int error; int now; int start_time; start_time = g_time3(); if (self->sck != 0) { g_tcp_close(self->sck); self->sck = 0; } if (self->mode == TRANS_MODE_TCP) /* tcp */ { self->sck = g_tcp_socket(); if (self->sck < 0) { self->status = TRANS_STATUS_DOWN; return 1; } g_tcp_set_non_blocking(self->sck); while (1) { error = g_tcp_connect(self->sck, server, port); if (error == 0) { break; } else { if (timeout < 1) { self->status = TRANS_STATUS_DOWN; return 1; } now = g_time3(); if (now - start_time < timeout) { g_sleep(timeout / 5); } else { self->status = TRANS_STATUS_DOWN; return 1; } } } } else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ { self->sck = g_tcp_local_socket(); if (self->sck < 0) { self->status = TRANS_STATUS_DOWN; return 1; } g_tcp_set_non_blocking(self->sck); while (1) { error = g_tcp_local_connect(self->sck, port); if (error == 0) { break; } else { if (timeout < 1) { self->status = TRANS_STATUS_DOWN; return 1; } now = g_time3(); if (now - start_time < timeout) { g_sleep(timeout / 5); } else { self->status = TRANS_STATUS_DOWN; return 1; } } } } else { self->status = TRANS_STATUS_DOWN; return 1; } if (error == -1) { if (g_tcp_last_error_would_block(self->sck)) { now = g_time3(); if (now - start_time < timeout) { timeout = timeout - (now - start_time); } else { timeout = 0; } if (g_tcp_can_send(self->sck, timeout)) { self->status = TRANS_STATUS_UP; /* ok */ self->type1 = TRANS_TYPE_CLIENT; /* client */ return 0; } } return 1; } self->status = TRANS_STATUS_UP; /* ok */ self->type1 = TRANS_TYPE_CLIENT; /* client */ return 0; }
int APP_CC trans_write_copy_s(struct trans *self, struct stream *out_s) { int size; int sent; struct stream *wait_s; struct stream *temp_s; char *out_data; if (self->status != TRANS_STATUS_UP) { return 1; } /* try to send any left over */ if (trans_send_waiting(self, 0) != 0) { /* error */ self->status = TRANS_STATUS_DOWN; return 1; } out_data = out_s->data; sent = 0; size = (int) (out_s->end - out_s->data); if (self->wait_s == 0) { /* if no left over, try to send this new data */ if (g_tcp_can_send(self->sck, 0)) { sent = self->trans_send(self, out_s->data, size); if (sent > 0) { out_data += sent; size -= sent; } else if (sent == 0) { return 1; } else { if (!g_tcp_last_error_would_block(self->sck)) { return 1; } } } } if (size < 1) { return 0; } /* did not send right away, have to copy */ make_stream(wait_s); init_stream(wait_s, size); if (self->si != 0) { if ((self->si->cur_source != 0) && (self->si->cur_source != self->my_source)) { self->si->source[self->si->cur_source] += size; wait_s->source = self->si->source + self->si->cur_source; } } out_uint8a(wait_s, out_data, size); s_mark_end(wait_s); wait_s->p = wait_s->data; if (self->wait_s == 0) { self->wait_s = wait_s; } else { temp_s = self->wait_s; while (temp_s->next != 0) { temp_s = temp_s->next; } temp_s->next = wait_s; } return 0; }
int APP_CC trans_send_waiting(struct trans *self, int block) { struct stream *temp_s; int bytes; int sent; int timeout; int cont; timeout = block ? 100 : 0; cont = 1; while (cont) { if (self->wait_s != 0) { temp_s = self->wait_s; if (g_tcp_can_send(self->sck, timeout)) { bytes = (int) (temp_s->end - temp_s->p); sent = self->trans_send(self, temp_s->p, bytes); if (sent > 0) { temp_s->p += sent; if (temp_s->source != 0) { temp_s->source[0] -= sent; } if (temp_s->p >= temp_s->end) { self->wait_s = temp_s->next; free_stream(temp_s); } } else if (sent == 0) { return 1; } else { if (!g_tcp_last_error_would_block(self->sck)) { return 1; } } } else if (block) { /* check for term here */ if (self->is_term != 0) { if (self->is_term()) { /* term */ return 1; } } } } else { break; } cont = block; } return 0; }
/* return error */ int DEFAULT_CC lib_mod_connect(struct mod *mod) { int error; int len; int i; int index; int use_uds; struct stream *s; char con_port[256]; int retry = 0; int send_error = 0; int rc = 0; unsigned int nbytes; char pidfile[128]; char ip[16]; char cookie[33]; char sessionid[128]; char sessiontoken[128]; struct passwd pwd; struct passwd *pwdresult; char pwdbuffer[16384]; char message[256]; char reply[256]; int sock; struct sockaddr_in server; json_t *request; json_t *response; json_t *display; json_error_t js_error; mod->server_msg(mod, "GoPCNX started connection", 0); sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { mod->server_msg(mod, "Socket creation failed", 0); return 1; } server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_family = AF_INET; server.sin_port = htons(9999); if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { mod->server_msg(mod, "Server connection failed", 0); return 1; } request = json_object(); json_object_set(request, "username", json_string(mod->username)); json_object_set(request, "password", json_string(mod->password)); json_object_set(request, "ip", json_string("127.0.0.1")); json_object_set(request, "link", json_string("lan")); display = json_object(); json_object_set(display, "width", json_integer(mod->width)); json_object_set(display, "height", json_integer(mod->height)); json_object_set(request, "display", display); json_decref(display); g_snprintf(message, sizeof(message)-1, "%s\n", json_dumps(request, 0)); json_decref(request); if (send(sock, message, strlen(message), 0) < 0) { mod->server_msg(mod, "Server request failed", 0); return 1; } if (recv(sock, reply, sizeof(reply), 0) < 0) { mod->server_msg(mod, "Server reply failed", 0); return 1; } response = json_loads(reply, 0, &js_error); if (response == NULL) { mod->server_msg(mod, "Decoding response failed", 0); return 1; } else { json_t *nxsession = json_object_get(response, "session"); json_t *err = json_object_get(response, "err"); int resume = json_is_true(json_object_get(response, "resume")); if (err) { mod->server_msg(mod, json_string_value(err), 0); return 1; } else if (resume) { resize_nxproxy(mod); } else { char sessionstash[512]; const char *cookie = json_string_value(json_object_get(nxsession, "cookie")); const char *host = json_string_value(json_object_get(nxsession, "host")); json_int_t port = json_integer_value(json_object_get(nxsession, "port")); getpwnam_r(mod->username, &pwd, pwdbuffer, sizeof(pwdbuffer), &pwdresult); if (pwdresult == NULL) { mod->server_msg(mod, "Uid lookup failed", 0); return 1; } if (!start_nxproxy(mod, cookie, (int)port)) { mod->server_msg(mod, "nxproxy failed to start", 0); return 1; } json_decref(nxsession); } } json_decref(response); LIB_DEBUG(mod, "in lib_mod_connect"); /* clear screen */ mod->server_begin_update(mod); mod->server_set_fgcolor(mod, 0); mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); mod->server_end_update(mod); mod->server_msg(mod, "started connecting", 0); /* only support 8, 15, 16, and 24 bpp connections from rdp client */ if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24) { mod->server_msg(mod, "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } if (g_strcmp(mod->ip, "") == 0) { mod->server_msg(mod, "error - no ip set", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } make_stream(s); g_snprintf(con_port, 255, "%s", mod->port); use_uds = 0; if (con_port[0] == '/') { use_uds = 1; } mod->sck_closed = 0; i = 0; RECONNECT: while (1) { if (use_uds) { mod->sck = g_tcp_local_socket(); } else { mod->sck = g_tcp_socket(); g_tcp_set_non_blocking(mod->sck); g_tcp_set_no_delay(mod->sck); } /* mod->server_msg(mod, "connecting...", 0); */ if (use_uds) { error = g_tcp_local_connect(mod->sck, con_port); } else { error = g_tcp_connect(mod->sck, mod->ip, con_port); } if (error == -1) { 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); */ } } if (error == 0) { break; } g_tcp_close(mod->sck); mod->sck = 0; i++; if (i >= 20) { mod->server_msg(mod, "connection problem, giving up", 0); break; } g_sleep(500); } if (error == 0) { if (use_uds) { lib_mod_log_peer(mod); } } if (error == 0) { /* send version message */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 301); out_uint32_le(s, 0); out_uint32_le(s, 0); out_uint32_le(s, 0); out_uint32_le(s, 1); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } if (error == 0) { /* send screen size message */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 300); out_uint32_le(s, mod->width); out_uint32_le(s, mod->height); out_uint32_le(s, mod->bpp); out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } if (error == 0) { /* send invalidate message */ init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 200); /* x and y */ i = 0; out_uint32_le(s, i); /* width and height */ i = ((mod->width & 0xffff) << 16) | mod->height; out_uint32_le(s, i); out_uint32_le(s, 0); out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); send_error = lib_send(mod, s->data, len); } if (send_error) { if (retry < 50) { g_tcp_close(mod->sck); mod->server_msg(mod, "Doing a retry", 0); retry++; g_sleep(1000); goto RECONNECT; } error = send_error; } free_stream(s); if (error != 0) { mod->server_msg(mod, "some problem", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } else { mod->server_msg(mod, "connected ok", 0); mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); } LIB_DEBUG(mod, "out lib_mod_connect"); return 0; }
/* return error */ int DEFAULT_CC lib_mod_connect(struct mod* mod) { int error; int len; int i; int index; int use_uds; struct stream* s; char con_port[256]; LIB_DEBUG(mod, "in lib_mod_connect"); /* clear screen */ mod->server_begin_update(mod); mod->server_set_fgcolor(mod, 0); mod->server_fill_rect(mod, 0, 0, mod->width, mod->height); mod->server_end_update(mod); mod->server_msg(mod, "started connecting", 0); /* only support 8, 15, 16, and 24 bpp connections from rdp client */ if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24) { mod->server_msg(mod, "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } if (g_strcmp(mod->ip, "") == 0) { mod->server_msg(mod, "error - no ip set", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } make_stream(s); g_sprintf(con_port, "%s", mod->port); use_uds = 0; if (con_port[0] == '/') { use_uds = 1; } mod->sck_closed = 0; i = 0; while (1) { if (use_uds) { mod->sck = g_tcp_local_socket(); } else { mod->sck = g_tcp_socket(); } g_tcp_set_non_blocking(mod->sck); g_tcp_set_no_delay(mod->sck); mod->server_msg(mod, "connecting...", 0); if (use_uds) { error = g_tcp_local_connect(mod->sck, con_port); } else { error = g_tcp_connect(mod->sck, mod->ip, con_port); } if (error == -1) { 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); } } if (error == 0) { break; } g_tcp_close(mod->sck); mod->sck = 0; i++; if (i >= 4) { mod->server_msg(mod, "connection problem, giving up", 0); break; } g_sleep(250); } if (error == 0) { init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 300); out_uint32_le(s, mod->width); out_uint32_le(s, mod->height); out_uint32_le(s, mod->bpp); out_uint32_le(s, mod->rfx); /* send rfx flag */ s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } if (error == 0) { init_stream(s, 8192); s_push_layer(s, iso_hdr, 4); out_uint16_le(s, 103); out_uint32_le(s, 200); /* x and y */ i = 0; out_uint32_le(s, i); /* width and height */ i = ((mod->width & 0xffff) << 16) | mod->height; out_uint32_le(s, i); out_uint32_le(s, 0); out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); out_uint32_le(s, len); lib_send(mod, s->data, len); } free_stream(s); if (error != 0) { mod->server_msg(mod, "some problem", 0); LIB_DEBUG(mod, "out lib_mod_connect error"); return 1; } else { mod->server_msg(mod, "connected ok", 0); mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0); } LIB_DEBUG(mod, "out lib_mod_connect"); return 0; }