/* 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; }
/* * 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); }
boolean transport_disconnect(rdpTransport* transport) { if (transport->layer == TRANSPORT_LAYER_TLS) tls_disconnect(transport->tls); return tcp_disconnect(transport->tcp); }
/* * 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); }
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; }
/* * 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); }
/** * Disconnect the current imap connection if any is open. */ static void imap_disconnect(void) { if (imap_connection) { tcp_disconnect(imap_connection); imap_connection = NULL; } }
int nego_tcp_disconnect(NEGO *nego) { if (nego->tcp_connected) tcp_disconnect(nego->iso->tcp); nego->tcp_connected = 0; return 1; }
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 ); }
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; }
/* 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); }
/* * 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); }
/* * 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); }
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; }
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; }
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; }
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; }
/* * 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; }
/* 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; }
/** * 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; } } }
/* 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; }
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; }
/* Disconnect from the ISO layer */ void iso_disconnect(void) { iso_send_msg(ISO_PDU_DR); tcp_disconnect(); }
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); }
int sserver_disconnect(const struct protocol_interface *protocol) { if(tcp_disconnect()) return CVSPROTO_FAIL; return CVSPROTO_SUCCESS; }
/* 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; }
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; }
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; }
int server_disconnect(const struct protocol_interface *protocol) { tcp_disconnect(); return CVSPROTO_SUCCESS; }
/* 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; }