示例#1
0
文件: iso.c 项目: OSSystems/RDesktop
/* Establish a connection up to the ISO layer */
RD_BOOL
iso_connect(char *server, char *username, RD_BOOL reconnect)
{
	uint8 code = 0;

	if (!tcp_connect(server))
		return False;

	if (reconnect)
	{
		iso_send_msg(ISO_PDU_CR);
	}
	else
	{
		iso_send_connection_request(username);
	}

	if (iso_recv_msg(&code, NULL) == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	return True;
}
示例#2
0
/*
 * pru_detach() detaches the TCP protocol from the socket.
 * If the protocol state is non-embryonic, then can't
 * do this directly: have to initiate a pru_disconnect(),
 * which may finish later; embryonic TCB's can just
 * be discarded here.
 */
static void
tcp_usr_detach(netmsg_t msg)
{
	struct socket *so = msg->base.nm_so;
	int error = 0;
	struct inpcb *inp;
	struct tcpcb *tp;
	TCPDEBUG0;

	inp = so->so_pcb;

	/*
	 * If the inp is already detached it may have been due to an async
	 * close.  Just return as if no error occured.
	 *
	 * It's possible for the tcpcb (tp) to disconnect from the inp due
	 * to tcp_drop()->tcp_close() being called.  This may occur *after*
	 * the detach message has been queued so we may find a NULL tp here.
	 */
	if (inp) {
		if ((tp = intotcpcb(inp)) != NULL) {
			TCPDEBUG1();
			tp = tcp_disconnect(tp);
			TCPDEBUG2(PRU_DETACH);
		}
	}
	lwkt_replymsg(&msg->lmsg, error);
}
示例#3
0
boolean transport_disconnect(rdpTransport* transport)
{
	if (transport->layer == TRANSPORT_LAYER_TLS)
		tls_disconnect(transport->tls);

	return tcp_disconnect(transport->tcp);
}
示例#4
0
/*
 * Initiate disconnect from peer.
 * If connection never passed embryonic stage, just drop;
 * else if don't need to let data drain, then can just drop anyways,
 * else have to begin TCP shutdown process: mark socket disconnecting,
 * drain unread data, state switch to reflect user close, and
 * send segment (e.g. FIN) to peer.  Socket will be really disconnected
 * when peer sends FIN and acks ours.
 *
 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
 */
static int
tcp_usr_disconnect(struct socket *so)
{
	struct inpcb *inp;
	struct tcpcb *tp = NULL;
	int error = 0;

	TCPDEBUG0;
	INP_INFO_WLOCK(&V_tcbinfo);
	inp = sotoinpcb(so);
	KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL"));
	INP_WLOCK(inp);
	if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
		error = ECONNRESET;
		goto out;
	}
	tp = intotcpcb(inp);
	TCPDEBUG1();
	tcp_disconnect(tp);
out:
	TCPDEBUG2(PRU_DISCONNECT);
	INP_WUNLOCK(inp);
	INP_INFO_WUNLOCK(&V_tcbinfo);
	return (error);
}
示例#5
0
BOOL transport_disconnect(rdpTransport* transport)
{
	BOOL status = TRUE;

	if (transport->layer == TRANSPORT_LAYER_TLS)
		status &= tls_disconnect(transport->TlsIn);

	if (transport->layer == TRANSPORT_LAYER_TSG || transport->layer == TRANSPORT_LAYER_TSG_TLS)
	{
		tsg_disconnect(transport->tsg);
	}
	else
	{
		status &= tcp_disconnect(transport->TcpIn);
	}

	if (transport->async)
	{
		if (transport->stopEvent)
		{
			SetEvent(transport->stopEvent);
			WaitForSingleObject(transport->thread, INFINITE);

			CloseHandle(transport->thread);
			CloseHandle(transport->stopEvent);

			transport->thread = NULL;
			transport->stopEvent = NULL;
		}
	}

	return status;
}
示例#6
0
/*
 * TCP socket is closed.  Start friendly disconnect.
 */
static void
tcp_usr_close(struct socket *so)
{
	struct inpcb *inp;
	struct tcpcb *tp = NULL;
	TCPDEBUG0;

	inp = sotoinpcb(so);
	KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL"));

	INP_INFO_WLOCK(&V_tcbinfo);
	INP_WLOCK(inp);
	KASSERT(inp->inp_socket != NULL,
	    ("tcp_usr_close: inp_socket == NULL"));

	/*
	 * If we still have full TCP state, and we're not dropped, initiate
	 * a disconnect.
	 */
	if (!(inp->inp_flags & INP_TIMEWAIT) &&
	    !(inp->inp_flags & INP_DROPPED)) {
		tp = intotcpcb(inp);
		TCPDEBUG1();
		tcp_disconnect(tp);
		TCPDEBUG2(PRU_CLOSE);
	}
	if (!(inp->inp_flags & INP_DROPPED)) {
		SOCK_LOCK(so);
		so->so_state |= SS_PROTOREF;
		SOCK_UNLOCK(so);
		inp->inp_flags |= INP_SOCKREF;
	}
	INP_WUNLOCK(inp);
	INP_INFO_WUNLOCK(&V_tcbinfo);
}
示例#7
0
/**
 * Disconnect the current imap connection if any is open.
 */
static void imap_disconnect(void)
{
	if (imap_connection)
	{
		tcp_disconnect(imap_connection);
		imap_connection = NULL;
	}
}
示例#8
0
文件: nego.c 项目: g-reno/FreeRDP-old
int nego_tcp_disconnect(NEGO *nego)
{
	if (nego->tcp_connected)
		tcp_disconnect(nego->iso->tcp);

	nego->tcp_connected = 0;
	return 1;
}
示例#9
0
文件: tcp.c 项目: ghostflame/ministry
void tcp_close_host( HOST *h )
{
    tcp_disconnect( &(h->net->sock), h->net->name );
    debug( "Closed connection from host %s.", h->net->name );

    // give us a moment
    usleep( 10000 );
    mem_free_host( &h );
}
示例#10
0
long tcp_abort (TCPSTREAM *stream)
{
  if (stream->tcpsi >= 0) {	/* no-op if no socket */
				/* nuke the socket */
    tcp_disconnect (&(stream->tcpsi));
    stream->tcpsi = stream->tcpso = -1;
  }
  return NIL;
}
示例#11
0
文件: iso.c 项目: g-reno/FreeRDP-old
/* Disconnect from the ISO layer */
void
iso_disconnect(rdpIso * iso)
{
	x224_send_dst_src_class(iso, X224_TPDU_DISCONNECT_REQUEST);
#ifndef DISABLE_TLS
	if (iso->mcs->sec->tls)
		tls_disconnect(iso->mcs->sec->tls);
#endif
	tcp_disconnect(iso->tcp);
}
示例#12
0
/*
 * Initiate disconnect from peer.
 * If connection never passed embryonic stage, just drop;
 * else if don't need to let data drain, then can just drop anyways,
 * else have to begin TCP shutdown process: mark socket disconnecting,
 * drain unread data, state switch to reflect user close, and
 * send segment (e.g. FIN) to peer.  Socket will be really disconnected
 * when peer sends FIN and acks ours.
 *
 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
 */
static int
tcp_usr_disconnect(struct socket *so)
{
	int s = splnet();
	int error = 0;
	struct inpcb *inp = sotoinpcb(so);
	struct tcpcb *tp;

	COMMON_START();
	tp = tcp_disconnect(tp);
	COMMON_END(PRU_DISCONNECT);
}
示例#13
0
/*
 * Initiate disconnect from peer.
 * If connection never passed embryonic stage, just drop;
 * else if don't need to let data drain, then can just drop anyways,
 * else have to begin TCP shutdown process: mark socket disconnecting,
 * drain unread data, state switch to reflect user close, and
 * send segment (e.g. FIN) to peer.  Socket will be really disconnected
 * when peer sends FIN and acks ours.
 *
 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
 */
static void
tcp_usr_disconnect(netmsg_t msg)
{
	struct socket *so = msg->disconnect.base.nm_so;
	int error = 0;
	struct inpcb *inp;
	struct tcpcb *tp;

	COMMON_START(so, inp, 1);
	tp = tcp_disconnect(tp);
	COMMON_END(PRU_DISCONNECT);
}
示例#14
0
int main(int argc, char **argv)
{
  char msg[2048] = {0};
  stream_t req, res;
  struct tcp_t *tcp;
  const char * address = "www.google.com";
  const char * port = "80";

  if (argv[1])
    address = argv[1];

  if (argv[2])
    port = argv[2];

  sprintf(msg, "GET / HTTP/1.1\nHost: %s\n\n", address);

  /* allocate and setup io streams*/
  stream_init(&req, 4096);
  stream_init(&res, 4096);

  stream_out_uint8p(&req, msg, strlen(msg));
  stream_mark_end(&req);

  /* initialize tcp */
  tcp_init();

  /* setup tcp and connect*/
  tcp = tcp_new();
  tcp_set_property(tcp, TCP_PROP_ADDRESS, address);
  tcp_set_property(tcp, TCP_PROP_PORT, port);

#ifdef WITH_GNUTLS
  tcp_set_property(tcp, TCP_PROP_USE_TLS, atoi(port) == 443 ? "1" : "0");
#endif

  tcp_connect(tcp);

  /* write http request and recv response */
  tcp_send(tcp, &req);

  tcp_recv(tcp, &res, 4096);

  fprintf(stdout,"%s", res.data);

  tcp_disconnect(tcp);

  tcp_destroy(tcp);

  tcp_deinit();

  return 0;
}
示例#15
0
int http_download_photo(char *path, char *email)
{
	struct connection *conn;
	struct connect_options conn_opts = {0};
	int error_code;
	int rc;

	if (!open_socket_lib()) return 0;

	rc = 0;

	if ((conn = tcp_connect("simplemail.sourceforge.net", 80, &conn_opts, &error_code)))
	{
		char *line;
		int download = 0;

		tcp_write(conn,"GET /gallery_get_image.php?",sizeof("GET /gallery_get_image.php?")-1);
		tcp_write(conn,email,strlen(email));
		tcp_write(conn," HTTP/1.0\r\nhost: simplemail.sourceforge.net\r\n\r\n",sizeof(" HTTP/1.0\r\nhost: simplemail.sourceforge.net\r\n\r\n")-1);

		while ((line = tcp_readln(conn)))
		{
			if (!mystrnicmp("Content-Type: image/",line,20)) download = 1;
			if (line[0] == 10 && line[1] == 0) break;
		}

		if (download)
		{
			FILE *fp = fopen(path,"wb");
			if (fp)
			{
				int got;
				char buf[1024];
				while ((got = tcp_read(conn,buf,1024))>0)
				{
					fwrite(buf,1,got,fp);
				}
				rc = 1;
				fclose(fp);
			}
		}

		tcp_disconnect(conn);
	}
	close_socket_lib();
	return rc;
}
示例#16
0
static void https_shutdown(struct http_client_ctx *ctx)
{
	if (!ctx->https.tid) {
		return;
	}

	/* Empty the fifo just in case there is any received packets
	 * still there.
	 */
	while (1) {
		struct rx_fifo_block *rx_data;

		rx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.rx_fifo,
				     K_NO_WAIT);
		if (!rx_data) {
			break;
		}

		net_pkt_unref(rx_data->pkt);

		k_mem_pool_free(&rx_data->block);
	}

	k_fifo_cancel_wait(&ctx->https.mbedtls.ssl_ctx.rx_fifo);

	/* Let the ssl_rx() run if there is anything there waiting */
	k_yield();

	mbedtls_ssl_close_notify(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_free(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_config_free(&ctx->https.mbedtls.conf);
	mbedtls_ctr_drbg_free(&ctx->https.mbedtls.ctr_drbg);
	mbedtls_entropy_free(&ctx->https.mbedtls.entropy);

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_x509_crt_free(&ctx->https.mbedtls.ca_cert);
#endif

	tcp_disconnect(ctx);

	NET_DBG("HTTPS thread %p stopped for %p", ctx->https.tid, ctx);

	k_thread_abort(ctx->https.tid);
	ctx->https.tid = 0;
}
示例#17
0
文件: transport.c 项目: 4hosi/FreeRDP
BOOL transport_disconnect(rdpTransport* transport)
{
	BOOL status = TRUE;

	if (transport->layer == TRANSPORT_LAYER_TLS)
		status &= tls_disconnect(transport->TlsIn);

	if (transport->layer == TRANSPORT_LAYER_TSG)
	{
		tsg_disconnect(transport->tsg);
	}
	else
	{
		status &= tcp_disconnect(transport->TcpIn);
	}

	return status;
}
示例#18
0
/*
 * pru_detach() detaches the TCP protocol from the socket.
 * If the protocol state is non-embryonic, then can't
 * do this directly: have to initiate a pru_disconnect(),
 * which may finish later; embryonic TCB's can just
 * be discarded here.
 */
static int
tcp_usr_detach(struct socket *so)
{
	int s = splnet();
	int error = 0;
	struct inpcb *inp = sotoinpcb(so);
	struct tcpcb *tp;
	TCPDEBUG0;

	if (inp == 0) {
		splx(s);
		return EINVAL;	/* XXX */
	}
	tp = intotcpcb(inp);
	TCPDEBUG1();
	tp = tcp_disconnect(tp);

	TCPDEBUG2(PRU_DETACH);
	splx(s);
	return error;
}
示例#19
0
文件: iso.c 项目: RPG-7/reactos
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(char *server)
{
	uint8 code = 0;

	if (!tcp_connect(server))
		return False;

	iso_send_msg(ISO_PDU_CR);

	if (iso_recv_msg(&code, NULL) == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	return True;
}
示例#20
0
/**
 * The entry point for the imap thread. It just go into the wait state and
 * then frees all resources when finished
 *
 * @param test
 */
static void imap_thread_entry(void *test)
{
	if (thread_parent_task_can_contiue())
	{
		thread_wait(NULL,NULL,NULL,0);

		imap_free(imap_server);
		free(imap_folder);
		free(imap_local_path);

		if (imap_connection)
		{
			tcp_disconnect(imap_connection);
			imap_connection = NULL;
		}

		if (imap_socket_lib_open)
		{
			close_socket_lib();
			imap_socket_lib_open = 0;
		}
	}
}
示例#21
0
文件: iso.c 项目: hoangduit/reactos
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(RDPCLIENT * This, char *server, char *cookie)
{
	uint8 code = 0;

	if (!tcp_connect(This, server))
		return False;

	if (!iso_send_connection_request(This, cookie)) // BUGBUG should we really pass the cookie here?
		return False;

	if (iso_recv_msg(This, &code, NULL) == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect(This);
		return False;
	}

	return True;
}
示例#22
0
static void https_handler(struct http_client_ctx *ctx,
			  struct k_sem *startup_sync)
{
	struct tx_fifo_block *tx_data;
	struct http_client_request req;
	size_t len;
	int ret;

	/* First mbedtls specific initialization */
	ret = https_init(ctx);

	k_sem_give(startup_sync);

	if (ret < 0) {
		return;
	}

reset:
	http_parser_init(&ctx->parser, HTTP_RESPONSE);
	ctx->rsp.data_len = 0;

	/* Wait that the sender sends the data, and the peer to respond to.
	 */
	tx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.tx_fifo, K_FOREVER);
	if (tx_data) {
		/* Because the req pointer might disappear as it is controlled
		 * by application, copy the data here.
		 */
		memcpy(&req, tx_data->req, sizeof(req));
	} else {
		NET_ASSERT(tx_data);
		goto reset;
	}

	print_info(ctx, ctx->req.method);

	/* If the connection is not active, then re-connect */
	ret = tcp_connect(ctx);
	if (ret < 0 && ret != -EALREADY) {
		k_sem_give(&ctx->req.wait);
		goto reset;
	}

	mbedtls_ssl_session_reset(&ctx->https.mbedtls.ssl);
	mbedtls_ssl_set_bio(&ctx->https.mbedtls.ssl, ctx, ssl_tx,
			    ssl_rx, NULL);

	/* SSL handshake. The ssl_rx() function will be called next by
	 * mbedtls library. The ssl_rx() will block and wait that data is
	 * received by ssl_received() and passed to it via fifo. After
	 * receiving the data, this function will then proceed with secure
	 * connection establishment.
	 */
	/* Waiting SSL handshake */
	do {
		ret = mbedtls_ssl_handshake(&ctx->https.mbedtls.ssl);
		if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
		    ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
				goto close;
			}

			if (ret < 0) {
				print_error("mbedtls_ssl_handshake returned "
					    "-0x%x", ret);
				goto close;
			}
		}
	} while (ret != 0);

	ret = http_request(ctx, &req, BUF_ALLOC_TIMEOUT);

	k_mem_pool_free(&tx_data->block);

	if (ret < 0) {
		NET_DBG("Send error (%d)", ret);
		goto close;
	}

	NET_DBG("Read HTTPS response");

	do {
		len = ctx->rsp.response_buf_len - 1;
		memset(ctx->rsp.response_buf, 0, ctx->rsp.response_buf_len);

		ret = mbedtls_ssl_read(&ctx->https.mbedtls.ssl,
				       ctx->rsp.response_buf, len);
		if (ret == 0) {
			goto close;
		}

		if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
		    ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
			continue;
		}

		if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
			NET_DBG("Connection was closed gracefully");
			goto close;
		}

		if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
			NET_DBG("Connection was reset by peer");
			goto close;
		}

		if (ret == -EIO) {
			NET_DBG("Response received, waiting another ctx %p",
				ctx);
			goto next;
		}

		if (ret < 0) {
			print_error("mbedtls_ssl_read returned -0x%x", ret);
			goto close;
		}

		/* The data_len will count how many bytes we have read,
		 * this value is passed to user supplied response callback
		 * by on_body() and on_message_complete() functions.
		 */
		ctx->rsp.data_len += ret;

		ret = http_parser_execute(&ctx->parser,
					  &ctx->settings,
					  ctx->rsp.response_buf,
					  ret);
		if (!ret) {
			goto close;
		}

		ctx->rsp.data_len = 0;

		if (ret > 0) {
			/* Get more data */
			ret = MBEDTLS_ERR_SSL_WANT_READ;
		}
	} while (ret < 0);

close:
	/* If there is any pending data that have not been processed yet,
	 * we need to free it here.
	 */
	if (ctx->https.mbedtls.ssl_ctx.rx_pkt) {
		net_pkt_unref(ctx->https.mbedtls.ssl_ctx.rx_pkt);
		ctx->https.mbedtls.ssl_ctx.rx_pkt = NULL;
		ctx->https.mbedtls.ssl_ctx.frag = NULL;
	}

	NET_DBG("Resetting HTTPS connection %p", ctx);

	tcp_disconnect(ctx);

next:
	mbedtls_ssl_close_notify(&ctx->https.mbedtls.ssl);

	goto reset;
}
示例#23
0
文件: iso.c 项目: RPG-7/reactos
/* Disconnect from the ISO layer */
void
iso_disconnect(void)
{
	iso_send_msg(ISO_PDU_DR);
	tcp_disconnect();
}
示例#24
0
文件: tcp_usr.c 项目: fjanssen/Car2X
int
tcp_usrreq(struct socket * so, 
   struct mbuf *  m,
   struct mbuf *  nam)
{
   struct inpcb * inp;
   struct tcpcb * tp;
   int   error =  0;
   int   req;

#ifdef DO_TCPTRACE
   int   ostate;
#endif

   req = so->so_req;    /* get request from socket struct */
   inp = sotoinpcb(so);
   /*
    * When a TCP is attached to a socket, then there will be
    * a (struct inpcb) pointed at by the socket, and this
    * structure will point at a subsidary (struct tcpcb).
    */
   if (inp == 0 && req != PRU_ATTACH) 
   {
      return (EINVAL);
   }

   if (inp)
      tp = intotcpcb(inp);
   else  /* inp and tp not set, make sure this is OK: */
   { 
      if (req == PRU_ATTACH)
         tp = NULL;  /* stifle compiler warnings about using unassigned tp*/
      else
      {
         dtrap(); /* programming error? */
         return EINVAL;
      }
   }

   switch (req) 
   {
   /*
    * TCP attaches to socket via PRU_ATTACH, reserving space,
    * and an internet control block.
    */
   case PRU_ATTACH:
      if (inp) 
      {
         error = EISCONN;
         break;
      }
      error = tcp_attach(so);
      if (error)
         break;
      if ((so->so_options & SO_LINGER) && so->so_linger == 0)
         so->so_linger = TCP_LINGERTIME;
#ifdef   DO_TCPTRACE
      SETTP(tp, sototcpcb(so));
#endif
      break;

   /*
    * PRU_DETACH detaches the TCP protocol from the socket.
    * If the protocol state is non-embryonic, then can't
    * do this directly: have to initiate a PRU_DISCONNECT,
    * which may finish later; embryonic TCB's can just
    * be discarded here.
    */
   case PRU_DETACH:
      if (tp->t_state > TCPS_LISTEN)
         SETTP(tp, tcp_disconnect(tp));
      else
         SETTP(tp, tcp_close(tp));
      break;

   /*
    * Give the socket an address.
    */
   case PRU_BIND:

      /* bind is quite different for IPv4 and v6, so we use two 
       * seperate pcbbind routines. so_domain was checked for 
       * validity way up in t_bind()
       */
#ifdef IP_V4
      if(inp->inp_socket->so_domain == AF_INET)
      {
         error = in_pcbbind(inp, nam);
         break;
      }
#endif /* IP_V4 */
#ifdef IP_V6
      if(inp->inp_socket->so_domain == AF_INET6)
      {
         error = ip6_pcbbind(inp, nam);
         break;
      }
#endif /* IP_V6 */
      dtrap();    /* not v4 or v6? */
      error = EINVAL;
      break;
   /*
    * Prepare to accept connections.
    */
   case PRU_LISTEN:
      if (inp->inp_lport == 0)
         error = in_pcbbind(inp, (struct mbuf *)0);
      if (error == 0)
         tp->t_state = TCPS_LISTEN;
      break;

   /*
    * Initiate connection to peer.
    * Create a template for use in transmissions on this connection.
    * Enter SYN_SENT state, and mark socket as connecting.
    * Start keep-alive timer, and seed output sequence space.
    * Send initial segment on connection.
    */
   case PRU_CONNECT:
      if (inp->inp_lport == 0) 
      {

#ifdef IP_V4
#ifndef IP_V6  /* v4 only */
      error = in_pcbbind(inp, (struct mbuf *)0);
#else    /* dual mode */
      if(so->so_domain == AF_INET)
         error = in_pcbbind(inp, (struct mbuf *)0);
      else
         error = ip6_pcbbind(inp, (struct mbuf *)0);
#endif   /* end dual mode code */
#else    /* no v4, v6 only */
      error = ip6_pcbbind(inp, (struct mbuf *)0);
#endif   /* end v6 only */

         if (error)
            break;
      }

#ifdef IP_V4
#ifndef IP_V6  /* v4 only */
      error = in_pcbconnect(inp, nam);
#else    /* dual mode */
      if(so->so_domain == AF_INET)
         error = in_pcbconnect(inp, nam);
      else
         error = ip6_pcbconnect(inp, nam);
#endif   /* end dual mode code */
#else    /* no v4, v6 only */
      error = ip6_pcbconnect(inp, nam);
#endif   /* end v6 only */

      if (error)
         break;
      tp->t_template = tcp_template(tp);
      if (tp->t_template == 0) 
      {

#ifdef IP_V4
#ifndef IP_V6  /* v4 only */
         in_pcbdisconnect(inp);
#else    /* dual mode */
         if(so->so_domain == AF_INET)
            in_pcbdisconnect(inp);
         else
            ip6_pcbdisconnect(inp);
#endif   /* end dual mode code */
#else    /* no v4, v6 only */
         ip6_pcbdisconnect(inp);
#endif   /* end v6 only */

         error = ENOBUFS;
         break;
      }

      soisconnecting(so);
      tcpstat.tcps_connattempt++;
      tp->t_state = TCPS_SYN_SENT;
      tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
      tp->iss = tcp_iss; 
      tcp_iss += (tcp_seq)(TCP_ISSINCR/2);
      tcp_sendseqinit(tp);
      error = tcp_output(tp);
      if (!error)
         TCP_MIB_INC(tcpActiveOpens);     /* keep MIB stats */
      break;

   /*
    * Create a TCP connection between two sockets.
    */
   case PRU_CONNECT2:
      error = EOPNOTSUPP;
      break;

   /*
    * Initiate disconnect from peer.
    * If connection never passed embryonic stage, just drop;
    * else if don't need to let data drain, then can just drop anyways,
    * else have to begin TCP shutdown process: mark socket disconnecting,
    * drain unread data, state switch to reflect user close, and
    * send segment (e.g. FIN) to peer.  Socket will be really disconnected
    * when peer sends FIN and acks ours.
    *
    * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
    */
   case PRU_DISCONNECT:
      SETTP(tp, tcp_disconnect(tp));
      break;

   /*
    * Accept a connection.  Essentially all the work is
    * done at higher levels; just return the address
    * of the peer, storing through addr.
    */
   case PRU_ACCEPT: 
   {
         struct sockaddr_in * sin   =  mtod(nam,   struct sockaddr_in *);
#ifdef IP_V6
         struct sockaddr_in6 * sin6 = mtod(nam,   struct sockaddr_in6 *);
#endif

#ifdef IP_V6
         if (so->so_domain == AF_INET6)
         {
            nam->m_len = sizeof (struct sockaddr_in6);
            sin6->sin6_port = inp->inp_fport;
            sin6->sin6_family = AF_INET6;
            IP6CPY(&sin6->sin6_addr, &inp->ip6_faddr);
         }
#endif

#ifdef IP_V4
         if (so->so_domain == AF_INET)
         {
            nam->m_len = sizeof (struct sockaddr_in);
            sin->sin_family = AF_INET;
            sin->sin_port = inp->inp_fport;
            sin->sin_addr = inp->inp_faddr;
         }
#endif
         if ( !(so->so_domain == AF_INET) &&
              !(so->so_domain == AF_INET6)
             )
         {
            dprintf("*** PRU_ACCEPT bad domain = %d\n", so->so_domain);
            dtrap();
         } 
         TCP_MIB_INC(tcpPassiveOpens);    /* keep MIB stats */
         break;
      }

   /*
    * Mark the connection as being incapable of further output.
    */
   case PRU_SHUTDOWN:
      socantsendmore(so);
      tp = tcp_usrclosed(tp);
      if (tp)
         error = tcp_output(tp);
      break;

   /*
    * After a receive, possibly send window update to peer.
    */
   case PRU_RCVD:
      (void) tcp_output(tp);
      break;

   /*
    * Do a send by putting data in output queue and updating urgent
    * marker if URG set.  Possibly send more data.
    */
   case PRU_SEND:
      if (so->so_pcb == NULL)
      {                    /* Return EPIPE error if socket is not connected */
         error = EPIPE;
         break;
      }
      sbappend(&so->so_snd, m);
      error = tcp_output(tp);
      if (error == ENOBUFS)
         sbdropend(&so->so_snd,m);  /* Remove data from socket buffer */
      break;

   /*
    * Abort the TCP.
    */
   case PRU_ABORT:
      SETTP(tp, tcp_drop(tp, ECONNABORTED));
      break;

   case PRU_SENSE:
      /*      ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat; */
      dtrap();    /* does this ever happen? */
      return (0);

   case PRU_RCVOOB:
      if ((so->so_oobmark == 0 &&
          (so->so_state & SS_RCVATMARK) == 0) ||
#ifdef SO_OOBINLINE
       so->so_options & SO_OOBINLINE ||
#endif
       tp->t_oobflags & TCPOOB_HADDATA) 
       {
         error = EINVAL;
         break;
      }
      if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) 
      {
         error = EWOULDBLOCK;
         break;
      }
      m->m_len = 1;
      *mtod(m, char *) = tp->t_iobc;
      if ((MBUF2LONG(nam) & MSG_PEEK) == 0)
         tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
      break;

   case PRU_SENDOOB:
      if (so->so_pcb == NULL)
      {                    /* Return EPIPE error if socket is not connected */
         error = EPIPE;
         break;
      }
      if (sbspace(&so->so_snd) == 0) 
      {
         m_freem(m);
         error = ENOBUFS;
         break;
      }
      /*
       * According to RFC961 (Assigned Protocols),
       * the urgent pointer points to the last octet
       * of urgent data.  We continue, however,
       * to consider it to indicate the first octet
       * of data past the urgent section.
       * Otherwise, snd_up should be one lower.
       */
      sbappend(&so->so_snd, m);
      tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
      tp->t_force = 1;
      error = tcp_output(tp);
      if (error == ENOBUFS)
         sbdropend(&so->so_snd,m);  /* Remove data from socket buffer */
      tp->t_force = 0;
      break;

   case PRU_SOCKADDR:

   /* sockaddr and peeraddr have to switch based on IP type */
#ifdef IP_V4
#ifndef IP_V6  /* v4 only */
      in_setsockaddr(inp, nam);
#else /* dual mode */
      if(so->so_domain == AF_INET6)
         ip6_setsockaddr(inp, nam);
      else
         in_setsockaddr(inp, nam);
#endif   /* dual mode */
#else    /* IP_V6 */
         ip6_setsockaddr(inp, nam);
#endif
      break;         

   case PRU_PEERADDR:
#ifdef IP_V4
#ifndef IP_V6  /* v4 only */
      in_setpeeraddr(inp, nam);
#else /* dual mode */
      if(so->so_domain == AF_INET6)
         ip6_setpeeraddr(inp, nam);
      else
         in_setpeeraddr(inp, nam);
#endif   /* dual mode */
#else    /* IP_V6 */
         ip6_setpeeraddr(inp, nam);
#endif
      break;

   case PRU_SLOWTIMO:
      SETTP(tp, tcp_timers(tp, (int)MBUF2LONG(nam)));
#ifdef DO_TCPTRACE
      req |= (long)nam << 8;        /* for debug's sake */
#endif
      break;

      default:
      panic("tcp_usrreq");
   }
#ifdef DO_TCPTRACE
   if (tp && (so->so_options & SO_DEBUG))
      tcp_trace("usrreq: state: %d, tcpcb: %x, req: %d",
    ostate, tp, req);
#endif
   return (error);
}
示例#25
0
int sserver_disconnect(const struct protocol_interface *protocol)
{
	if(tcp_disconnect())
		return CVSPROTO_FAIL;
	return CVSPROTO_SUCCESS;
}
示例#26
0
/* Establish a connection up to the ISO layer */
RD_BOOL
iso_connect(char *server, char *username, char *domain, char *password,
	    RD_BOOL reconnect, uint32 * selected_protocol)
{
	STREAM s;
	uint8 code;
	uint32 neg_proto;

	g_negotiate_rdp_protocol = True;

	neg_proto = PROTOCOL_SSL;

#ifdef WITH_CREDSSP
	if (!g_use_password_as_pin)
		neg_proto |= PROTOCOL_HYBRID;
	else if (g_sc_csp_name || g_sc_reader_name || g_sc_card_name || g_sc_container_name)
		neg_proto |= PROTOCOL_HYBRID;
	else
		warning("Disables CredSSP due to missing smartcard information for SSO.\n");
#endif

      retry:
	*selected_protocol = PROTOCOL_RDP;
	code = 0;

	if (!tcp_connect(server))
		return False;

	iso_send_connection_request(username, neg_proto);

	s = iso_recv_msg(&code, NULL);
	if (s == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8))
	{
		/* handle RDP_NEG_REQ response */
		const char *reason = NULL;

		uint8 type = 0, flags = 0;
		uint16 length = 0;
		uint32 data = 0;

		in_uint8(s, type);
		in_uint8(s, flags);
		in_uint16(s, length);
		in_uint32(s, data);

		if (type == RDP_NEG_FAILURE)
		{
			RD_BOOL retry_without_neg = False;

			switch (data)
			{
				case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
					reason = "SSL with user authentication required by server";
					break;
				case SSL_NOT_ALLOWED_BY_SERVER:
					reason = "SSL not allowed by server";
					retry_without_neg = True;
					break;
				case SSL_CERT_NOT_ON_SERVER:
					reason = "no valid authentication certificate on server";
					retry_without_neg = True;
					break;
				case INCONSISTENT_FLAGS:
					reason = "inconsistent negotiation flags";
					break;
				case SSL_REQUIRED_BY_SERVER:
					reason = "SSL required by server";
					break;
				case HYBRID_REQUIRED_BY_SERVER:
					reason = "CredSSP required by server";
					break;
				default:
					reason = "unknown reason";
			}

			tcp_disconnect();

			if (retry_without_neg)
			{
				fprintf(stderr,
					"Failed to negotiate protocol, retrying with plain RDP.\n");
				g_negotiate_rdp_protocol = False;
				goto retry;
			}

			fprintf(stderr, "Failed to connect, %s.\n", reason);
			return False;
		}

		if (type != RDP_NEG_RSP)
		{
			tcp_disconnect();
			error("Expected RDP_NEG_RSP, got type = 0x%x\n", type);
			return False;
		}

		/* handle negotiation response */
		if (data == PROTOCOL_SSL)
		{
			if (!tcp_tls_connect())
			{
				/* failed to connect using cssp, let retry with plain TLS */
				tcp_disconnect();
				neg_proto = PROTOCOL_RDP;
				goto retry;
			}
			/* do not use encryption when using TLS */
			g_encryption = False;
			fprintf(stderr, "Connection established using SSL.\n");
		}
#ifdef WITH_CREDSSP
		else if (data == PROTOCOL_HYBRID)
		{
			if (!cssp_connect(server, username, domain, password, s))
			{
				/* failed to connect using cssp, let retry with plain TLS */
				tcp_disconnect();
				neg_proto = PROTOCOL_SSL;
				goto retry;
			}

			/* do not use encryption when using TLS */
			fprintf(stderr, "Connection established using CredSSP.\n");
			g_encryption = False;
		}
#endif
		else if (data == PROTOCOL_RDP)
		{
			fprintf(stderr, "Connection established using plain RDP.\n");
		}
		else if (data != PROTOCOL_RDP)
		{
			tcp_disconnect();
			error("Unexpected protocol in negotiation response, got data = 0x%x.\n",
			      data);
			return False;
		}

		*selected_protocol = data;
	}
	return True;
}
示例#27
0
int http_client_send_req(struct http_client_ctx *ctx,
			 struct http_client_request *req,
			 http_response_cb_t cb,
			 u8_t *response_buf,
			 size_t response_buf_len,
			 void *user_data,
			 s32_t timeout)
{
	int ret;

	if (!response_buf || response_buf_len == 0) {
		return -EINVAL;
	}

	ctx->rsp.response_buf = response_buf;
	ctx->rsp.response_buf_len = response_buf_len;

	client_reset(ctx);

	/* HTTPS connection is established in https_handler() */
	if (!ctx->is_https) {
		ret = tcp_connect(ctx);
		if (ret < 0 && ret != -EALREADY) {
			NET_DBG("TCP connect error (%d)", ret);
			return ret;
		}
	}

	if (!req->host) {
		req->host = ctx->server;
	}

	ctx->req.host = req->host;
	ctx->req.method = req->method;
	ctx->req.user_data = user_data;

	ctx->rsp.cb = cb;

#if defined(CONFIG_HTTPS)
	if (ctx->is_https) {
		struct tx_fifo_block *tx_data;
		struct k_mem_block block;

		ret = start_https(ctx);
		if (ret != 0 && ret != -EALREADY) {
			NET_ERR("HTTPS init failed (%d)", ret);
			goto out;
		}

		ret = k_mem_pool_alloc(ctx->https.pool, &block,
				       sizeof(struct tx_fifo_block),
				       BUF_ALLOC_TIMEOUT);
		if (ret < 0) {
			goto out;
		}

		tx_data = block.data;
		tx_data->req = req;

		memcpy(&tx_data->block, &block, sizeof(struct k_mem_block));

		/* We need to pass the HTTPS request to HTTPS thread because
		 * of the mbedtls API stack size requirements.
		 */
		k_fifo_put(&ctx->https.mbedtls.ssl_ctx.tx_fifo,
			   (void *)tx_data);

		/* Let the https_handler() to start to process the message.
		 *
		 * Note that if the timeout > 0 or is K_FOREVER, then this
		 * yield is not really necessary as the k_sem_take() will
		 * let the https handler thread to run. But if the timeout
		 * is K_NO_WAIT, then we need to let the https handler to
		 * run now.
		 */
		k_yield();
	} else
#endif /* CONFIG_HTTPS */
	{
		print_info(ctx, ctx->req.method);

		ret = http_request(ctx, req, BUF_ALLOC_TIMEOUT);
		if (ret < 0) {
			NET_DBG("Send error (%d)", ret);
			goto out;
		}
	}

	if (timeout != 0 && k_sem_take(&ctx->req.wait, timeout)) {
		ret = -ETIMEDOUT;
		goto out;
	}

	if (timeout == 0) {
		return -EINPROGRESS;
	}

	return 0;

out:
	tcp_disconnect(ctx);

	return ret;
}
示例#28
0
int http_download(char *uri, void **buf_ptr, int *buf_len_ptr)
{
	int rc = 0;

	if (!mystrnicmp(uri,"http://",7))
	{
		int port;
		char *path_buf;
		char *port_buf;
		struct connection *conn;
		struct connect_options connect_opts = {0};
		int error_code;
		char *server;

		uri += 7;

		if (!(server = mystrdup(uri))) return 0;
		if (!(path_buf = strchr(server,'/')))
		{
			free(server);
			return 0;
		}
		port_buf = strchr(uri,':');

		if (port_buf > path_buf) port_buf = NULL;
		if (port_buf)
		{
			*port_buf = 0;
			port = atoi(port_buf+1);
		} else
		{
			*path_buf = 0;
			port = 80;
		}

		if (open_socket_lib())
		{
			if ((conn = tcp_connect(server,port,&connect_opts,&error_code)))
			{
				FILE *fh;

				if ((fh = tmpfile()))
				{
					int download = 1;
					char *line;

					tcp_write(conn,"GET /", sizeof("GET /")-1);
					tcp_write(conn,path_buf+1,strlen(path_buf+1));
					tcp_write(conn," HTTP/1.0\r\nhost: ", sizeof(" HTTP/1.0\r\nhost: ")-1);
					tcp_write(conn,server,strlen(server));
					tcp_write(conn,"\r\n\r\n",sizeof("\r\n\r\n")-1);

					while ((line = tcp_readln(conn)))
					{
						if (line[0] == 10 && line[1] == 0) break;
					}

					if (download)
					{
						int got;
						int len = 0;
						char buf[1024];
						while ((got = tcp_read(conn,buf,1024))>0)
						{
							fwrite(buf,1,got,fh);
							len += got;
						}

						if ((*buf_ptr = malloc(len)))
						{
							fseek(fh,0,SEEK_SET);
							fread(*buf_ptr,1,len,fh);
							*buf_len_ptr = len;
							rc = 1;
						}
					}
					fclose(fh);
				}
				tcp_disconnect(conn);
			}
			close_socket_lib();
		}
		free(server);
	}
	return rc;
}
示例#29
0
int server_disconnect(const struct protocol_interface *protocol)
{
	tcp_disconnect();
	return CVSPROTO_SUCCESS;
}
示例#30
0
/* Establish a connection up to the ISO layer */
RD_BOOL
iso_connect(char *server, char *username, RD_BOOL reconnect, uint32 * selected_protocol)
{
	STREAM s;
	uint8 code;

	g_negotiate_rdp_protocol = True;

      retry:
	*selected_protocol = PROTOCOL_RDP;
	code = 0;

	if (!tcp_connect(server))
		return False;

	if (reconnect)
	{
		iso_send_msg(ISO_PDU_CR);
	}
	else
	{
		iso_send_connection_request(username);
	}

	s = iso_recv_msg(&code, NULL);
	if (s == NULL)
		return False;

	if (code != ISO_PDU_CC)
	{
		error("expected CC, got 0x%x\n", code);
		tcp_disconnect();
		return False;
	}

	if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8))
	{
		/* handle RDP_NEG_REQ response */
		const char *reason = NULL;

		uint8 type = 0, flags = 0;
		uint16 length = 0;
		uint32 data = 0;

		in_uint8(s, type);
		in_uint8(s, flags);
		in_uint16(s, length);
		in_uint32(s, data);

		if (type == RDP_NEG_FAILURE)
		{
			switch (data)
			{
				case SSL_REQUIRED_BY_SERVER:
					reason = "SSL required by server";
					break;
				case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
					reason = "SSL with user authentication required by server";
					break;
				case SSL_NOT_ALLOWED_BY_SERVER:
					reason = "SSL not allowed by server";
					break;
				case SSL_CERT_NOT_ON_SERVER:
					reason = "SSL certificated not on server";
					break;
				case INCONSISTENT_FLAGS:
					reason = "inconsistent flags";
					break;
				case HYBRID_REQUIRED_BY_SERVER:
					reason = "hybrid authentication (CredSSP) required by server";
					break;
				default:
					reason = "unknown reason";
			}

			tcp_disconnect();
			warning("RDP protocol negotiation failed with reason: %s (error 0x%x),\n",
				reason, data);
			warning("retrying without negotiation using plain RDP protocol.\n");

			g_negotiate_rdp_protocol = False;
			goto retry;
		}

		if (type != RDP_NEG_RSP)
		{
			tcp_disconnect();
			error("expected RDP_NEG_RSP, got type = 0x%x\n", type);
			warning("retrying without negotiation using plain RDP protocol.\n");

			g_negotiate_rdp_protocol = False;
			goto retry;
		}

		/* handle negotiation response */
		if (data == PROTOCOL_SSL)
		{
			DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL\n"));
			if (!tcp_tls_connect())
			{
				tcp_disconnect();
				DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL FAILED\n"));
				return False;
			}

			/* do not use encryption when using TLS */
			g_encryption = False;
		}
		else if (data != PROTOCOL_RDP)
		{
			tcp_disconnect();
			error("unexpected protocol in neqotiation response, got data = 0x%x.\n",
			      data);
			return False;
		}

		*selected_protocol = data;
	}
	return True;
}