Ejemplo n.º 1
0
Archivo: evcom.c Proyecto: bernd/node
enum evcom_stream_state
evcom_stream_state (evcom_stream *stream)
{
  if (stream->recvfd < 0 && stream->sendfd && stream->flags == 0) {
    return EVCOM_INITIALIZED;
  }

  if (stream->recvfd < 0 && stream->sendfd < 0) return EVCOM_CLOSED;

  if (!CONNECTED(stream)) return EVCOM_CONNECTING;

  if (GOT_CLOSE(stream)) {
    if (READABLE(stream)) {
      return EVCOM_CONNECTED_RO;
    } else {
      return EVCOM_CLOSING;
    }
  }

  if (READABLE(stream) && WRITABLE(stream)) return EVCOM_CONNECTED_RW;

  if (WRITABLE(stream)) return EVCOM_CONNECTED_WO;

  if (READABLE(stream)) return EVCOM_CONNECTED_RO;

  return EVCOM_CLOSING;
}
Ejemplo n.º 2
0
int socket_tcpu_init(struct socket *sock)
{
    struct tcp_data *td;
    struct tcpcb *tp;

    
    td = (struct tcp_data *)tcp_data_init(sock);
    
    BUFFOUTEND(sock) =  BUFF_OUT(sock)->buf + MAX_BUF;
    tp=GET_TCPCB(sock); 
    
    tp->t_state =  TCPS_CLOSED;
    tp->sock = sock;
    
    /* init timer */
    tp->t_timer[0]  = 0;
    tp->t_timer[1]  = 0;
    tp->t_timer[2]  = TCPTV_KEEP_INIT;
    tp->t_timer[3]  = 0;
    
    tp->t_template  = NULL;
    CONNECTED(sock) = 0;
  
    return ((int) sock);
}
Ejemplo n.º 3
0
void decr_mysql2_client(mysql_client_wrapper *wrapper)
{
  wrapper->refcount--;

  if (wrapper->refcount == 0) {
#ifndef _WIN32
    if (CONNECTED(wrapper) && !wrapper->automatic_close) {
      /* The client is being garbage collected while connected. Prevent
       * mysql_close() from sending a mysql-QUIT or from calling shutdown() on
       * the socket by invalidating it. invalidate_fd() will drop this
       * process's reference to the socket only, while a QUIT or shutdown()
       * would render the underlying connection unusable, interrupting other
       * processes which share this object across a fork().
       */
      if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
        fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely\n");
        close(wrapper->client->net.fd);
      }
      wrapper->client->net.fd = -1;
    }
#endif

    nogvl_close(wrapper);
    xfree(wrapper->client);
    xfree(wrapper);
  }
}
Ejemplo n.º 4
0
/* call-seq:
 *    client.ping
 *
 * Checks whether the connection to the server is working. If the connection
 * has gone down and auto-reconnect is enabled an attempt to reconnect is made.
 * If the connection is down and auto-reconnect is disabled, ping returns an
 * error.
 */
static VALUE rb_mysql_client_ping(VALUE self) {
  GET_CLIENT(self);

  if (!CONNECTED(wrapper)) {
    return Qfalse;
  } else {
    return (VALUE)rb_thread_call_without_gvl(nogvl_ping, wrapper->client, RUBY_UBF_IO, 0);
  }
}
Ejemplo n.º 5
0
// Disconnects port
void commDisconnect() {	// disconnects with serial port if connected
	HMENU hMenu;
	// Check if we're connected
	if (CONNECTED(TTYInfo)) {
		// Menu
		hMenu = GetMenu(ghWndMain);	// get the menu handle
		EnableMenuItem(hMenu, ID_FILE_CONNECT, MF_ENABLED); // enable the connect menu
		EnableMenuItem(hMenu, ID_FILE_DISCONNECT, MF_GRAYED | MF_DISABLED); // disable the connect menu
		EnableMenuItem(hMenu, ID_EDIT_SETTINGS, MF_ENABLED); // enable the TTY menu

		// lower DTR
		EscapeCommFunction(COMDEV(TTYInfo), CLRDTR);
		
		// Purge reads/writes, and I/O buffer
		PurgeComm(COMDEV(TTYInfo), PURGE_FLAGS);

		CloseHandle(COMDEV(TTYInfo)); // release the handle

		TTYInfo.fThreadDone = TRUE; // we want the thread to end
		CONNECTED(TTYInfo) = FALSE; // we are  now disconnected
	}
}
Ejemplo n.º 6
0
/*-----------------------------------------------------------------------------*/
void InitTTYInfo() {
	// Initialize general TTY info
	COMDEV(TTYInfo)		= NULL;
	CONNECTED(TTYInfo)	= FALSE;
	PORT(TTYInfo)		= '0';			// setting to 0 since we know nothing about
										// the current COM port configuration
	BAUDRATE(TTYInfo)	= CBR_9600;
	BYTESIZE(TTYInfo)	= 8;
	PARITY(TTYInfo)		= NOPARITY;
	STOPBITS(TTYInfo)	= ONESTOPBIT;

	InitFont();
	ClearTTYContents();
}
Ejemplo n.º 7
0
// Connects to, sets up and configures (if virgin) port.
void commConnect() {
	DCB dcb;
	HMENU hMenu;

	// Make sure we're not connected
	if (!CONNECTED(TTYInfo)) {
		// Menu
		hMenu = GetMenu(ghWndMain);	// get the menu handle
		EnableMenuItem(hMenu, ID_FILE_CONNECT, MF_GRAYED | MF_DISABLED); // disable the connect menu
		EnableMenuItem(hMenu, ID_FILE_DISCONNECT, MF_ENABLED); // enable the disconnect menu
		EnableMenuItem(hMenu, ID_EDIT_SETTINGS, MF_GRAYED | MF_DISABLED); // disable the TTY menu

		COMDEV(TTYInfo) = CreateFile(gszPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

		FillMemory(&dcb, sizeof(dcb), 0);

		dcb.BaudRate = BAUDRATE(TTYInfo);	// set the baud rate
		dcb.ByteSize = BYTESIZE(TTYInfo);	// set the data bits
		dcb.fParity = PARITY(TTYInfo);		// set the parity
		dcb.StopBits = STOPBITS(TTYInfo);	// set the stop bits

		SetCommState(COMDEV(TTYInfo), &dcb);	// update the COM port configuration

		CONNECTED(TTYInfo) = TRUE;	// we are now connected (hopefully)
	}
	// Start reading thread
	TTYInfo.hThread = CreateThread(
		NULL,	// security attributes
		0,		// inital thread stack size, in bytes
		commReadThread,		// address of thread function
		ghWndTerm,	// argument for new thread
		0,		// creation flags
		&TTYInfo.hThread
	);	// address of returned thread ID
	TTYInfo.fConnected = TRUE;
}
Ejemplo n.º 8
0
static VALUE disconnect_and_raise(VALUE self, VALUE error) {
  GET_CLIENT(self);

  wrapper->active_thread = Qnil;

  /* Invalidate the MySQL socket to prevent further communication.
   * The GC will come along later and call mysql_close to free it.
   */
  if (CONNECTED(wrapper)) {
    if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
      fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely, closing unsafely\n");
      close(wrapper->client->net.fd);
    }
    wrapper->client->net.fd = -1;
  }

  rb_exc_raise(error);
}
Ejemplo n.º 9
0
Archivo: evcom.c Proyecto: bernd/node
static int
stream__handshake (evcom_stream *stream)
{
  assert(SECURE(stream));

  int r = gnutls_handshake(stream->session);

  if (gnutls_error_is_fatal(r)) {
    stream->gnutls_errorno = r;
    stream->send_action = stream_send__close;
    stream->recv_action = stream_recv__close;
    return OKAY;
  }

  ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);

  if (r == GNUTLS_E_INTERRUPTED || r == GNUTLS_E_AGAIN) {
    if (0 == gnutls_record_get_direction((stream)->session)) {
      ev_io_start(D_LOOP_(stream) &(stream)->read_watcher); 
      ev_io_stop(D_LOOP_(stream) &(stream)->write_watcher); 
    } else {
      ev_io_stop(D_LOOP_(stream) &(stream)->read_watcher); 
      ev_io_start(D_LOOP_(stream) &(stream)->write_watcher);
    }
    assert(stream->recv_action == stream__handshake);
    assert(stream->send_action == stream__handshake);
    return AGAIN;
  }

  assert(!CONNECTED(stream));
  stream->flags |= EVCOM_CONNECTED;
  if (stream->on_connect) stream->on_connect(stream);

  /* evcom_stream_force_close might have been called. */
  if (stream->recvfd >= 0 && stream->sendfd >= 0) {
    ev_io_start(D_LOOP_(stream) &stream->read_watcher);
    ev_io_start(D_LOOP_(stream) &stream->write_watcher);

    stream->send_action = stream_send__data;
    stream->recv_action = stream_recv__data;
  }

  return OKAY;
}
Ejemplo n.º 10
0
Archivo: evcom.c Proyecto: bernd/node
static int
stream__connection_established (evcom_stream *stream)
{
  assert(!CONNECTED(stream));

#if EVCOM_HAVE_GNUTLS
  if (SECURE(stream)) {
    stream->send_action = stream__handshake;
    stream->recv_action = stream__handshake;
  } else
#endif
  {
    stream->flags |= EVCOM_CONNECTED;
    if (stream->on_connect) stream->on_connect(stream);

    stream->send_action = stream_send__data;
    stream->recv_action = stream_recv__data;
  }

  ev_io_start(D_LOOP_(stream) &stream->write_watcher);
  ev_io_start(D_LOOP_(stream) &stream->read_watcher);

  return OKAY;
}
Ejemplo n.º 11
0
static VALUE disconnect_and_mark_inactive(VALUE self) {
  GET_CLIENT(self);

  /* Check if execution terminated while result was still being read. */
  if (!NIL_P(wrapper->active_thread)) {
    if (CONNECTED(wrapper)) {
      /* Invalidate the MySQL socket to prevent further communication. */
#ifndef _WIN32
      if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
        rb_warn("mysql2 failed to invalidate FD safely, closing unsafely\n");
        close(wrapper->client->net.fd);
      }
#else
      close(wrapper->client->net.fd);
#endif
      wrapper->client->net.fd = -1;
    }
    /* Skip mysql client check performed before command execution. */
    wrapper->client->status = MYSQL_STATUS_READY;
    wrapper->active_thread = Qnil;
  }

  return Qnil;
}
Ejemplo n.º 12
0
int connect_tcpu(struct socket *sock, struct sockaddr_in *servaddr, 
		 int addrlen)
{
    struct tcpcb *tp;
    int error, res, timer;
    struct timeval timeout;
    struct sockaddr_in *laddr = (struct sockaddr_in *)(&sock->laddr);
    
    if((tp = GET_TCPCB(sock)) == NULL)
	return(-1);

    if (sock->state != SS_BOUND)
    {
	printf("tcp_connect: socket is not in bound state (%d != %d)\n",
		sock->state, SS_BOUND);
	return -1;
    }
    
    tcp_stack(tp,(struct sockaddr_in *)(&sock->laddr),servaddr);

    *(struct sockaddr_in *)(&tp->sock->raddr) = *servaddr;

/* Save the client and server addresses in the template, minimizing
   work when sending a packet to the server */
    
    tp->t_template->ti_dst.s_addr = servaddr->sin_addr.s_addr;
    tp->t_template->ti_dport = servaddr->sin_port;
    
    tp->t_template->ti_src.s_addr = laddr->sin_addr.s_addr;
    tp->t_template->ti_sport = laddr->sin_port;
  
/*
    tcpstat.tcps_connattempt++;
*/
    tp->t_template->ti_pr=IP_PROTO_TCP;
    tp->t_state                 = TCPS_SYN_SENT;
    tp->t_timer[TCPT_KEEP]      = TCPTV_KEEP_INIT;
    tp->iss                     = (tcp_seq) NOW();
    tcpu_sendseqinit(tp);

    if((error = tcpu_output(&tp)) < 0)
	return(-1);

  connect:
    timeout.tv_sec = 0;
    timeout.tv_usec = SLOW_TIMO;
    res=get_res(tp,&timeout);
    switch(res) 
    {
	case EVENT_ERROR: return(-1);
	case EVENT_TIMER: {
	    if((timer = slow_timo(tp->sock)) <= TCPT_NTIMERS)
		tcpu_timers(tp, timer);
	    else
		goto connect;  
	    break;
	}
	default:{
	    tcpu_input(&tp,res);
	    if(tp->t_state == TCPS_ESTABLISHED) {
			    CONNECTED(sock) = 1;
			    sock->state = SS_CONNECTED;
                            printf ("\n\nconnect_tcpu: good return\n\n\n");
			    return(1);
		}
	}
    }
    if((tp->t_state == TCPS_SYN_RECEIVED) || (tp->t_state == TCPS_SYN_SENT )) {
	goto connect;
    }
    
    
    printf ("connect_tcpu: bad return\n");
    PAUSE(TENTHS(1));
    return(-1); 
}
Ejemplo n.º 13
0
Archivo: evcom.c Proyecto: bernd/node
static int
stream_recv__data (evcom_stream *stream)
{
  char buf[EVCOM_CHUNKSIZE];
  size_t buf_size = EVCOM_CHUNKSIZE;
  ssize_t recved;

  while (READABLE(stream)) {
    assert(CONNECTED(stream));

    if (PAUSED(stream)) {
      stream->recv_action = stream_recv__wait_for_resume;
      return OKAY;
    }


#if EVCOM_HAVE_GNUTLS
    if (SECURE(stream)) {
      recved = gnutls_record_recv(stream->session, buf, buf_size);

      if (gnutls_error_is_fatal(recved)) {
        stream->gnutls_errorno = recved;
        stream->recv_action = stream_recv__close;
        return OKAY;
      }

      if (recved == GNUTLS_E_INTERRUPTED || recved == GNUTLS_E_AGAIN) {
        if (1 == gnutls_record_get_direction((stream)->session)) {
          fprintf(stderr, "(evcom) gnutls recv: unexpected switch direction!\n");
          ev_io_stop(D_LOOP_(stream) &(stream)->read_watcher); 
          ev_io_start(D_LOOP_(stream) &(stream)->write_watcher);
        }
        return AGAIN;
      }

      /* A server may also receive GNUTLS_E_REHANDSHAKE when a client has
       * initiated a andshake. In that case the server can only initiate a
       * handshake or terminate the connection. */
      if (recved == GNUTLS_E_REHANDSHAKE) {
        assert(WRITABLE(stream));
        stream->recv_action = stream__handshake;
        stream->send_action = stream__handshake;
        return OKAY;
      }
    } else 
#endif /* EVCOM_HAVE_GNUTLS */
    {
      recved = read(stream->recvfd, buf, buf_size);
    }

    if (recved < 0) {
      if (errno == EAGAIN || errno == EINTR) {
        assert(stream->recv_action == stream_recv__data);
        return AGAIN;
      } 
      
      if (errno != ECONNRESET) {
        evcom_perror("recv()", stream->errorno);
      }

      stream->errorno = errno;
      stream->recv_action = stream_recv__close;
      return OKAY;
    }

    ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);

    assert(recved >= 0);

    if (recved == 0) {
      stream->flags &= ~EVCOM_READABLE;
      ev_io_stop(D_LOOP_(stream) &stream->read_watcher);
      stream->recv_action = stream_recv__wait_for_close;
    }

    /* NOTE: EOF is signaled with recved == 0 on callback */
    if (stream->on_read) stream->on_read(stream, buf, recved);

    if (recved == 0) {
      return OKAY;
    }
  }
  return AGAIN;
}
Ejemplo n.º 14
0
Archivo: evcom.c Proyecto: bernd/node
/* Returns the number of bytes flushed to the buffer */
ssize_t
evcom_stream_write (evcom_stream *stream, const char *str, size_t len)
{
  if (!WRITABLE(stream) || GOT_CLOSE(stream)) {
    assert(0 && "Do not write to a closed stream");
    return -1;
  }

  ssize_t sent = 0;

  if ( stream->send_action == stream_send__wait_for_buf
    && evcom_queue_empty(&stream->out)
     ) 
  {
    assert(CONNECTED(stream));
#if EVCOM_HAVE_GNUTLS
    if (SECURE(stream)) {
      sent = gnutls_record_send(stream->session, str, len);

      if (gnutls_error_is_fatal(sent)) {
        stream->gnutls_errorno = sent;
        goto close;
      }
    } else
#endif // EVCOM_HAVE_GNUTLS
    {
      /* TODO use writev() here? */
      sent = nosigpipe_stream_send(stream, str, len);
    }

    if (sent < 0) {
      switch (errno) {
        case EPIPE:
          goto close;

        case EINTR:
        case EAGAIN:
          sent = 0;
          break;

        default:
          stream->errorno = errno;
          evcom_perror("send()", stream->errorno);
          goto close;
      }
    }
  } /* TODO else { memcpy to last buffer on head } */

  assert(sent >= 0);
  if ((size_t)sent == len) return sent; /* sent the whole buffer */

  len -= sent;
  str += sent;

  evcom_buf *b = evcom_buf_new(str, len);
  evcom_queue_insert_head(&stream->out, &b->queue);
  b->written = 0;

  assert(stream->sendfd >= 0);

  if (ATTACHED(stream)) {
    ev_io_start(D_LOOP_(stream) &stream->write_watcher);
  }
  return sent;

close:
  stream->send_action = stream_send__close;
  stream->recv_action = stream_recv__close;
  if (ATTACHED(stream)) {
    ev_io_start(D_LOOP_(stream) &stream->write_watcher);
  }
  return -1;
}
Ejemplo n.º 15
0
/* call-seq:
 *    client.closed?
 *
 * @return [Boolean]
 */
static VALUE rb_mysql_client_closed(VALUE self) {
  GET_CLIENT(self);
  return CONNECTED(wrapper) ? Qfalse : Qtrue;
}