Beispiel #1
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);
  }
  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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/* 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;
}
Beispiel #7
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;
}
Beispiel #8
0
/* 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;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
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;
}