Example #1
0
inline static bpt_node_t bpt_get_node_ptr(bpt_node_t n, int ndx) {
	if(n == NULL) {
		tb_error("node is null !!!\n");
		return NULL;
	}
	if(ndx > n->cnt ) {
		tb_error("pnp: index out of bounds !!\n");
		return NULL;
	}
	return (bpt_node_t)n->ptrs[ndx];
}
Example #2
0
inline static tb_Key_t bpt_get_node_key(bpt_node_t n, int ndx) {
	if(n == NULL) {
		tb_error("node is null !!!\n");
		return KINVAL;
	}
	if(ndx > n->cnt -1) {
		tb_error("pnk: index out of bounds !!\n");
		return KINVAL;
	}
	return (tb_Key_t)n->keys[ndx];
}
Example #3
0
rpc_sig_t Rpc_getMethod(Rpc_t Self, int methodId) {
	Pointer_t P = tb_Get(XRpc(Self)->methods, methodId);
	if(P) {
		return (rpc_sig_t)P2p(P);
	} else {
		tb_error("Rpc_getMethod[%d] : no such method !\n", methodId);
	}
	return NULL;
}
Example #4
0
Num_t tb_NumSet(Num_t N, int val) {
	if(tb_valid(N, TB_NUM, __FUNCTION__)) {
		void *p;

		if((p = tb_getMethod(N, OM_NUMSET))) {
			return ((Num_t(*)(Num_t, int val))p)(N, val);
		} else {
			tb_error("%p (%d:%s) [no numSet method]\n", N, N->isA, tb_nameOf(N->isA));
			set_tb_errno(TB_ERR_NO_SUCH_METHOD);
		}
	}
	return NULL;

}
int
tb_recv_from(tb_listener_t *listener, tb_session_t *session)
{

	session->last_trans = listener->protocol->f_recfrom(listener->sock_d, session->data,
			session->data_size, 0, (struct sockaddr*)session->addr_in, &session->addr_len);

	if(session->last_trans == -1)
	{
		tb_error(listener, "Error: recv_from", errno);
		listener->f_abort(listener);
	}

	return 0;
}
int
tb_send_to(tb_listener_t *listener, tb_session_t *session)
{
	int rc;

	rc = listener->protocol->f_sendto(listener->sock_d, session->data,
			session->data_size, 0, (struct sockaddr*)session->addr_in, session->addr_len);

	if(rc == -1)
	{
		tb_error(listener, "Error: send_to", errno);
		listener->f_abort(listener);
	}

	return 0;
}
int
tb_create_socket(tb_listener_t *listener)
{
	PRT_ACK("Create socket");
	listener->sock_d =
			listener->protocol->f_sock(listener->addr_info->ai_family,
			listener->addr_info->ai_socktype,
			listener->addr_info->ai_protocol);

	if(listener->sock_d == -1)
	{
		tb_error(listener, "Error: socket", errno);
		listener->f_abort(listener);
	}

	return 0;
}
int
tb_listen(tb_listener_t *listener)
{
	int rc = 0;

	tb_protocol_t *p = listener->protocol;

	rc = p->f_listen(listener->sock_d, 10);

	if(rc == -1)
	{
		tb_error(listener, "Error: listen : listen", errno);
		listener->f_abort(listener);
	}

	return rc;
}
int
tb_bind(tb_listener_t *listener)
{
	int rc;
	rc =
		listener->protocol->f_bind(listener->sock_d,
		listener->addr_info->ai_addr,
		listener->addr_info->ai_addrlen);

	if(rc == -1)
	{
		tb_error(listener, "Error: bind", errno);
		listener->f_abort(listener);
	}

	return 0;
}
int
tb_connect(tb_listener_t *listener)
{
	PRT_ACK("Connecting");
	int rc;

	rc = listener->protocol->f_connect(listener->sock_d,
					listener->addr_info->ai_addr,
					listener->addr_info->ai_addrlen);

	if(rc == -1)
	{
		tb_error(listener, "Error: tb_connect", errno);
		listener->f_abort(listener);
	}

	return 0;
}
Example #11
0
Dict_t tb_dict_new(int keytype, int allow_dupes) {
	Dict_t O;
	pthread_once(&__class_registry_init_once, tb_classRegisterInit);

	if(kt_exists(keytype)) {

		O = tb_newParent(TB_DICT);

		O->isA   = TB_DICT;
		O->members->instance            = tb_xcalloc(1, sizeof(struct dict_extra));
		((struct dict_extra *)O->members->instance)->BplusTree = bpt_newTree(10, allow_dupes, keytype);

		if( fm->dbg) fm_addObject(O);

		return O;
	}
	tb_error("unknown/unregistered key type %d\n", keytype);
	return NULL;
}
tb_session_t
*tb_accept(tb_listener_t *listener)
{

	tb_protocol_t *p = listener->protocol;

	tb_session_t *session = tb_create_server_session();

	session->sock_d = p->f_accept(listener->sock_d,
			(struct sockaddr*)session->addr_in,
			&session->addr_len);

	if(session->sock_d == -1)
	{
		tb_error(listener, "Error: accept", errno);
		return session;
	}

	return session;
}
Example #13
0
/** read a line on a Socket_t using timeout and retries values as set in object.
 * \ingroup Socket
 * Target Socket_t must have been fully initialised by tb_Connect or tb_initServer. Read result is appended in 'msg' String_t.  
 *
 * @return number of read bytes, or -1 if error
 * Internally read is buffered for best performances. The first line found in the buffer is appended to Msg String_t. The remaining buffered data (if any) will be used on next tb_readSockLine or tb_readSock.
 *
 * \remarks ERROR:
 * in case of error tb_errno will be set to :
 * - TB_ERR_INVALID_OBJECT : So not a TB_SOCKET
 * - TB_ERR_BAD : msg is not a TB_STRING
 * 
 * @see tb_Socket, tb_writeSock, tb_writeSockBin, tb_readSockLine
*/
int tb_readSockLine(Socket_t S, String_t Msg) {
  fd_set set ;
  struct timeval tps ;
  int rc, retval;
	sock_members_t So;
	char buff[MAX_BUFFER];
	no_error;

	if(! TB_VALID(S,   TB_SOCKET)) {
		set_tb_errno(TB_ERR_INVALID_TB_OBJECT);
		return TB_ERR;
	}
	if(! TB_VALID(Msg, TB_STRING)) {
		set_tb_errno(TB_ERR_BAD);
		return TB_ERR;
	}

	So = XSock(S);

	if( So->buffer == NULL ) {
		So->buffer = tb_String(NULL);
	} else {
		if( tb_getSize(So->buffer) > 0 ) {
			char *s;
			if(( s = strchr(S2sz(So->buffer), '\n')) != NULL) {
				int len;

				len = 1+ (s - S2sz(So->buffer));
				tb_StrnAdd(Msg, len, -1, "%s", S2sz(So->buffer));
				tb_StrDel(So->buffer, 0, len);
				return len;
			}
		}
	}

  FD_ZERO(&set);
  FD_SET(So->sock, &set);
  tb_getSockTO(S, &(tps.tv_sec), &(tps.tv_usec));
 
	restart_r_select:
  rc = select(So->sock+1, &set, NULL, NULL, &tps);
  switch (rc)
    {
    case -1:
			if( errno == EINTR ) goto restart_r_select;
      tb_error("tb_readSockLine[%d]: select failed (%s)\n", 
							 So->sock, strerror(errno)); 
      // invalid fd ==> we're disconnected
      if( errno == EBADF ) So->status = TB_DISCONNECTED;
			set_tb_errno(TB_ERR_DISCONNECTED);
      retval = TB_ERR;
      break; 
    case 0:
      /* Time out */
      tb_notice("tb_readSockLine[%d]: select timed out\n", So->sock); 
      So->status = TB_TIMEDOUT;
      retval = TB_ERR;
      break ;
    default:
		restart_r_read:
#ifdef WITH_SSL
			if( So->ssl ) {
				rc = SSL_read(XSsl(S)->cx, buff, MAX_BUFFER-1);
				switch (SSL_get_error(XSsl(S)->cx,rc)) {
				case SSL_ERROR_NONE:
					buff[rc] = 0;
					tb_StrAdd(Msg, -1, "%s", buff);
					goto cutline;
				case SSL_ERROR_SYSCALL:
					if( errno ) {
						tb_error("tb_readSock[%d(SSL)]: read error (%s)\n",
										 So->sock, strerror(errno));
					}
					/* fall through */
				case SSL_ERROR_WANT_WRITE:
				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_X509_LOOKUP:
				case SSL_ERROR_ZERO_RETURN:
				case SSL_ERROR_SSL:
					ERR_print_errors_fp(stderr);
					return TB_ERR;
				}
			} else {
				set_nonblock_flag(So->sock, 1);
				rc = read(So->sock, buff, MAX_BUFFER-1);
				set_nonblock_flag(So->sock, 0);
			}
#else
			set_nonblock_flag(So->sock, 1);
			rc = read(So->sock, buff, MAX_BUFFER-1);
			set_nonblock_flag(So->sock, 0);
#endif
#ifdef WITH_SSL
    cutline:
#endif // WITH_SSL
      switch( rc ) {
      case -1:
				if( errno == EINTR|| errno == EWOULDBLOCK ) goto restart_r_read;
				if( errno != EWOULDBLOCK ) {
					tb_error("tb_readSockLine[%d]: read error (%s)\n", So->sock, strerror(errno));
					retval = TB_ERR;
					So->status = TB_DISCONNECTED;
					break;
				}
      case 0:  // eof
				tb_notice("tb_readSockLine[%d]: eof reached\n", So->sock);
				*buff = 0;
				tb_StrAdd(Msg, -1, "%S", So->buffer);
				retval = TB_ERR;
				tb_Clear(So->buffer);
				break;
      default:
				buff[rc] = 0; 
				tb_StrAdd(So->buffer, -1, "%s", buff);
				{
					char *s = strchr(S2sz(So->buffer), '\n');
					if( s ) {
						int len;
						len = 1+(s - S2sz(So->buffer)); 
						tb_StrnAdd(Msg, len, -1, "%s", S2sz(So->buffer));
						tb_StrDel(So->buffer, 0, len);
						retval = len;
					} else {
						goto restart_r_select;
					}
				}
				break;
      }
      break;
    }
  return retval;
}
Example #14
0
/** write binary on a Socket_t using timeout and retries values as set in object.
 * \ingroup Socket
 * Target Socket_t must have been fully initialised by tb_Connect or tb_initServer. 
 *
 * @return number of written bytes, or -1 if error
 *
 * see test/srv_test.c , test/socket_test.c in build tree
 *
 * \remarks ERROR:
 * in case of error tb_errno will be set to :
 * - TB_ERR_INVALID_OBJECT : So not a TB_SOCKET
 * - TB_ERR_BAD : msg is not a TB_STRING
 * 
 * @see tb_Socket, tb_writeSock, , tb_writeSockBin, tb_readSockLine
 * \todo fixme: use a pointer and a counter to remaining bytes to write for icomplete writes ...
 */
int tb_writeSockBin(Socket_t S, Raw_t raw) {
  fd_set set ;
  struct timeval tps ;
  int len, rc, remaining, retval = 0;
	char *msg;
	sock_members_t So;

	if(!TB_VALID(raw, TB_RAW)) {
		set_tb_errno(TB_ERR_BAD);
		return TB_KO;
	}
	
	if(!TB_VALID(S, TB_SOCKET)) {
		set_tb_errno(TB_ERR_INVALID_TB_OBJECT);
		return TB_ERR;
	}

	So = XSock(S);

	if(tb_getSockStatus(S) <= TB_DISCONNECTED) {
		return TB_ERR;
	}

  FD_ZERO(&set);
  FD_SET(So->sock,&set);

	msg = Raw_getData(raw);
	remaining = tb_getSize(raw);

 restart_w_select:
  tb_getSockTO(S, &tps.tv_sec, &tps.tv_usec);

  rc = select(FD_SETSIZE, NULL, &set, NULL, &tps);
  switch(rc)
    {
    case -1: 
			if( errno == EINTR ) goto restart_w_select;
      tb_error("tb_writeSock[%d]: select failed (%s)\n", So->sock, strerror(errno)); 
      // invalid fd ==> we're disconnected
      if( errno == EBADF    ||
					errno == ENOTSOCK ||
					errno == ENOTCONN ||
					errno == EPIPE ) So->status = TB_DISCONNECTED;
      retval = TB_ERR;
      break ;
    case 0:
      /* Time out */
      tb_notice("tb_writeSock[%d]: select timed out\n", So->sock); 
      So->status = TB_TIMEDOUT;
      retval = TB_KO;
      break ;
    default:
			if( ! FD_ISSET(So->sock, &set)) {
				tb_error("tb_readSock[%d]: select rc=%d but fd is not ready\n", 
								 So->sock, rc); 
				retval = TB_KO;
				break ;
			}

		restart_w_write:
#ifdef WITH_SSL
			if( So->ssl ) {
				rc=SSL_write(XSsl(S)->cx,msg , remaining);
				switch (SSL_get_error(XSsl(S)->cx,rc)) { 
				case SSL_ERROR_NONE:
					return rc;
				case SSL_ERROR_SYSCALL:
					if ((rc != 0) && errno ) {
						tb_error("tb_writeSock[%d(SSL)]: write error (%s)\n", 
										 So->sock, strerror(errno));
					}
					/* fall through */
				case SSL_ERROR_WANT_WRITE:
				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_X509_LOOKUP:
				case SSL_ERROR_ZERO_RETURN:
				case SSL_ERROR_SSL:
				default:
					ERR_print_errors_fp(stderr);
					return TB_ERR;
				}
			} else {
				set_nonblock_flag(So->sock, 1);
				rc = write(So->sock, msg, len = remaining);
				set_nonblock_flag(So->sock, 0);
			}
#else
			set_nonblock_flag(So->sock, 1);
			rc = write(So->sock, msg, len = remaining);
			set_nonblock_flag(So->sock, 0);
#endif
      switch( rc ) {
      case -1:
				if( errno == EINTR ) goto restart_w_write;
				tb_error("tb_writeSock[%d]: write error (%s)\n", So->sock, strerror(errno));
				So->status = TB_DISCONNECTED;
				retval = TB_ERR;
				break;
      default:
				retval += rc;
				if( rc != remaining ) {
					tb_error("tb_writeSock[%d]: incomplet write (%d/%d)\n", So->sock, rc, len); 
					msg       += rc;
					remaining -= rc;
					goto restart_w_select;
				}
				break ;
      }
      break ;
    }

  return retval;
}
Example #15
0
/** read on a Socket_t using timeout and retries values as set in object.
 * \ingroup Socket
 * Target Socket_t must have been fully initialised by tb_Connect or tb_initServer. Read result is appended in 'msg' String_t.  
 *
 * @return number of read bytes, or -1 if error.
 * Example:
 * \code
 * ...
 * String_t S = tb_String(NULL);
 * Socket_t So = tb_Socket(TB_TCP_UX, "/tmp/my_unix_sock", 0);
 * tb_Connect(So, 1, 1);
 * int rc;
 *
 * while(( rc = tb_readSock(So, S, 1024)) > 0);
 * switch( rc ) {
 * case -1: // error occurs
 * case  0: // read reached eof (or timed out)
 * ...
 * \endcode
 * S will contains a concatened string of all 1024's buffers read 
 *
 * other Examples : 
 * see test/srv_test.c , test/socket_test.c in build tree
 *
 * \remarks ERROR:
 * in case of error tb_errno will be set to :
 * - TB_ERR_INVALID_OBJECT : So not a TB_SOCKET
 * - TB_ERR_BAD : msg is not a TB_STRING
 * 
 * @see tb_Socket, tb_writeSock, tb_writeSockBin, tb_readSockLine
*/
int tb_readSock(Socket_t S, tb_Object_t Msg, int maxlen) {
  fd_set set ;
  struct timeval tps ;
  int rc, retval = 0;
	sock_members_t So;
	char buff[maxlen+1];

	no_error;

	if(! TB_VALID(S,   TB_SOCKET)) {
		set_tb_errno(TB_ERR_INVALID_TB_OBJECT);
		return TB_ERR;
	}

	if(! TB_VALID(Msg, TB_STRING) && ! TB_VALID(Msg, TB_RAW)) {
		set_tb_errno(TB_ERR_BAD);
		return TB_ERR;
	}

#ifdef WITH_XTI
	if( XSock(S)->addr_family   == TB_X25 ) {
		return tb_readSock_X25(S, Msg, maxlen);
	}
#endif


 
	So = XSock(S);


	if( So->buffer != NULL && tb_getSize(So->buffer) >0) {
		int n;
		n = TB_MIN( (maxlen), (tb_getSize(So->buffer)));
		tb_notice("readSock: already %d bytes in buffer\n", tb_getSize(So->buffer));
		if( n ) {
			if( tb_isA(Msg) == TB_STRING) {
				tb_StrnAdd(Msg, n, -1, "%S", So->buffer);
			} else {
			tb_RawAdd(Msg, n, -1, S2sz(So->buffer));
			}
			tb_StrDel(So->buffer, 0, n);
			if( n == maxlen) {
				return n;
			} else {
				maxlen -= n;
				retval = n;
			}
		}
	} 

	restart_r_select:

  FD_ZERO(&set);
  FD_SET(So->sock, &set);
  tb_getSockTO(S, &(tps.tv_sec), &(tps.tv_usec));

  rc = select(So->sock+1, &set, NULL, NULL, &tps);
  switch (rc)
    {
    case -1:
			if( errno == EINTR ) goto restart_r_select;
      tb_warn("tb_readSock[%d]: select failed (%s)\n", 
							 So->sock, strerror(errno)); 
      // invalid fd ==> we're disconnected
      if( errno == EBADF ) So->status = TB_DISCONNECTED;
			set_tb_errno(TB_ERR_DISCONNECTED);
      retval = TB_ERR;
      break; 
    case 0:
      /* Time out */
      tb_notice("tb_readSock[%d]: select timed out\n", So->sock); 
      So->status = TB_TIMEDOUT;
      retval = TB_KO;
			break ;
    default:
			if( ! FD_ISSET(So->sock, &set)) {
				tb_notice("tb_readSock[%d]: select rc=%d but fd is not ready\n", 
									So->sock, rc); 
				retval = TB_KO;
				break ;
			}
		restart_r_read:
#ifdef WITH_SSL
			if( So->ssl ) {
				tb_info("SSL_read: try to read %d bytes\n", maxlen);
				rc = SSL_read(XSsl(S)->cx, buff, maxlen);
				switch (SSL_get_error(XSsl(S)->cx,rc)) {
				case SSL_ERROR_NONE:
					buff[rc] = 0;
					tb_StrAdd(Msg, -1, "%s", buff);
					if( rc < maxlen ) {
						tb_info("SSL_read: got only %d/%d\n", rc, maxlen);
						maxlen -= rc;
						goto restart_r_select;
					}
					return rc;
				case SSL_ERROR_SYSCALL:
					if( errno ) {
						tb_warn("tb_readSock[%d(SSL)]: read error (%s)\n",
										 So->sock, strerror(errno));
					}
					/* fall through */
				case SSL_ERROR_WANT_WRITE:
				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_X509_LOOKUP:
				case SSL_ERROR_ZERO_RETURN:
				case SSL_ERROR_SSL:
					ERR_print_errors_fp(stderr);
					return TB_ERR;
				}
			} else {
				set_nonblock_flag(So->sock, 1);
				rc = read(So->sock, buff, maxlen);
				set_nonblock_flag(So->sock, 0);
			}
#else
			set_nonblock_flag(So->sock, 1);
			rc = read(So->sock, buff, maxlen);
			set_nonblock_flag(So->sock, 0);
#endif			

      switch( rc ) {
      case -1:
				if( errno == EINTR ) goto restart_r_read;
				if( errno != EWOULDBLOCK ) {
					tb_error("tb_readSock[%d]: read error (%s)\n", So->sock, strerror(errno));
					retval = TB_ERR;
					So->status = TB_DISCONNECTED;
					break;
				}
      case 0:  // eof
				*buff = 0;
      default:
				retval += rc;
				tb_RawAdd(Msg, rc, -1, buff); 
				break ;
      }
      break;
    }
  return retval;
}
Example #16
0
retcode_t tb_initSSL(Socket_t    S, 
										 enum ssl_mode  mode,       // SSL_CLIENT | SSL_SERVER
										 ssl_meth_t  method,     // SSL1 | SSL2 | SSL3 | TLS1
										 char      * CA_path,
										 char      * CA_file,
										 char      * cert,
										 char      * pwd,
										 char      * cipher) {
	SSL_METHOD * meth;
	sock_ssl_t m;

	tb_info("tb_initSSL in\n");

	if(!TB_VALID(S, TB_SOCKET)) {
		set_tb_errno(TB_ERR_INVALID_TB_OBJECT);
		return TB_ERR;
	}
	if(XSock(S)->ssl != NULL ) {
		tb_warn("tb_initSSL: Socket_t allready SSL initialized\n");
		set_tb_errno(TB_ERR_ALLREADY);
		return TB_ERR;
	}

	m = tb_xcalloc(1, sizeof(struct sock_ssl));
	XSock(S)->ssl = m;
	m->ssl_method = method;

	m->mode = method;


	if( CA_path ) m->CA_path = tb_xstrdup(CA_path);
	if( CA_file ) m->CA_file = tb_xstrdup(CA_file);
	if( cert ) 		m->cert    = tb_xstrdup(cert);
	if( pwd ) 		m->pwd     = tb_xstrdup(pwd);		
	if( cipher ) 	m->cipher  = tb_xstrdup(cipher);
	

	__tb_init_SSL_once();

	switch (m->ssl_method) {
  case 1:
		meth = (mode == SSL_CLIENT) ? SSLv23_client_method() : SSLv23_server_method();
    break;
  case 2:
		meth = (mode == SSL_CLIENT) ? SSLv2_client_method() : SSLv2_server_method();
    break;
  case 3:
		meth = (mode == SSL_CLIENT) ? SSLv3_client_method() : SSLv3_server_method();
    break;
  case 4:
		meth = (mode == SSL_CLIENT) ? TLSv1_client_method() : TLSv1_server_method();
    break;
	default:
		meth = NULL;
		goto err;
  }


	if (!(m->ctx = SSL_CTX_new(meth))) {
    tb_warn("tb_initSSL: Cannot create new SSL context\n");
    ERR_print_errors_fp(stderr);
		XSock(S)->status = TB_BROKEN;
		return TB_ERR; 
  }

	if(tb_errorlevel == TB_DEBUG) SSL_CTX_set_info_callback(m->ctx,info_cb);

  if(m->pwd) {
		SSL_CTX_set_default_passwd_cb(m->ctx, pass_cb);
		SSL_CTX_set_default_passwd_cb_userdata(m->ctx, S);
	}
	

	if(m->cert ) {
		if(SSL_CTX_use_certificate_file(m->ctx, m->cert, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			goto err;
		}
		if (SSL_CTX_use_PrivateKey_file(m->ctx, m->cert, SSL_FILETYPE_PEM) <= 0) {
			tb_error("tb_initSSL: Unable to get private key from '%s'\n", 
							 m->cert);
			ERR_print_errors_fp(stderr);
			goto err;
		}
		tb_info("privkey loaded\n");		
		if (!SSL_CTX_check_private_key(m->ctx)) {
			tb_error("tb_initSSL: Private key does not match the certificate public key\n");
			goto err;
		}
		tb_info("tb_initSSL: privkey validated\n");
		tb_info("tb_initSSL: certificate loaded\n");
	}

	if(mode == SSL_CLIENT) {
		SSL_CTX_set_session_cache_mode(m->ctx, SSL_SESS_CACHE_CLIENT);
	} else {
		SSL_CTX_set_session_cache_mode(m->ctx, SSL_SESS_CACHE_SERVER);
		SSL_CTX_set_session_id_context(m->ctx,  "try this one", 12);
	}

  if(m->CA_file || m->CA_path) {
		tb_info("tb_initSSL: loading CAs ...\n");
    if(!SSL_CTX_load_verify_locations(m->ctx, m->CA_file, m->CA_path)) {
			XSock(S)->status = TB_BROKEN;
      tb_warn("tb_initSSL: Cannot load verify locations %s and %s\n",
              m->CA_file, m->CA_path);
      ERR_print_errors_fp(stderr);
			goto err;
    }
		tb_info("tb_initSSL: CA  <%s/%s> loaded\n", m->CA_path, m->CA_file);
		SSL_CTX_set_verify(m->ctx, SSL_VERIFY_PEER, verify_cb);
		SSL_CTX_set_default_verify_paths(m->ctx);
  }

 /* Create and configure SSL connection. */

  if (!(m->cx = (SSL *)SSL_new(m->ctx))) {
    tb_warn("tb_initSSL: Cannot create new SSL context\n");
    ERR_print_errors_fp(stderr);
		goto err;
  }
	tb_info("tb_initSSL: ssl ctx initialized\n");

  /* Use OpenSSL ciphers -v to see the cipher strings and their SSL
   * versions, key exchange, authentication, encryption, and message
   * digest algorithms, and key length restrictions.  See the OpenSSL
   * for the syntax to combine ciphers, e.g. !SSLv2:RC4-MD5:RC4-SHA.
   * If you don't specify anything, you get the same as "DEFAULT", which
   * means "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP".
   */
  if(m->cipher) {
    if(!SSL_CTX_set_cipher_list(m->ctx, m->cipher)) {
      tb_warn("tb_inittSSL: Cannot use cipher list %s\n", m->cipher);
			goto err;
    }
		tb_info("tb_initSSL: cipher set to <%s>\n", m->cipher);
	}


	tb_info("tb_initSSL out\n");
	return TB_OK;

 err:
	// fixme: context not totally freed (CA_path, pwd ...)
	SSL_CTX_free(m->ctx);
	m->ctx = NULL;
	XSock(S)->status = TB_BROKEN;
	return TB_ERR;
}
Example #17
0
static int
go_test(test_test_state *state)
{
	int ret = TBEVENT_SUCCESS;

	if (state->loopdetect)
		return TBEVENT_SUCCESS;
	else
		state->loopdetect++;

top:
	switch (state->state) {
		case 0:
			ret = act_test_state_0(state);
			break;
		case 1:
			ret = act_test_state_1(state);
			break;
		case 2:
			ret = act_test_state_2(state);
			break;
		case 3:
			ret = act_test_state_3(state);
			break;
		case 4:
			ret = act_test_state_4(state);
			break;
		case 5:
			ret = act_test_state_5(state);
			break;
		case 6:
			ret = act_test_state_6(state);
			break;
		case 7:
			ret = act_test_state_7(state);
			break;
		case 8:
			ret = act_test_state_8(state);
			break;
		case 9:
			ret = act_test_state_9(state);
			break;
		case 10:
			ret = act_test_state_10(state);
			break;
		case 11:
			ret = act_test_state_11(state);
			break;
		case 12:
			ret = act_test_state_12(state);
			break;
		case 13:
			ret = act_test_state_13(state);
			break;
		case 14:
			ret = act_test_state_14(state);
			break;
		case 15:
			ret = act_test_state_15(state);
			break;
		case 16:
			ret = act_test_state_16(state);
			break;
		case 17:
			ret = act_test_state_17(state);
			break;
		case 18:
			ret = act_test_state_18(state);
			break;
		case 19:
			ret = act_test_state_19(state);
			break;
		case 20:
			ret = act_test_state_20(state);
			break;
		case 21:
			ret = fin_test_state_21(state);
			break;
		case 22:
			ret = fin_test_state_22(state);
			break;
		case 23:
			ret = fin_test_state_23(state);
			break;
		case 24:
			ret = TBEVENT_FINISH;
			break;
		default:
			log_warnx("go_test: invalid state %d", state->state);
			ret = TBOX_API_INVALID;
			goto out;
	}
	if (ret == TBEVENT_BLOCKDONE || ret == TBEVENT_SUCCESS) {
		state->state++;
		if (state->state >= 0 && state->state <= 23)
			goto top;
	} else if (ret == TBEVENT_CALLBACK) {
		ret = TBEVENT_CALLBACK;
		goto out;
	} else if (ret == TBEVENT_FINISH) {
		if (state->state >= 0 && state->state < 21)
			state->state = 21;
		else
			state->state = 23 + 1;
		if (state->state >= 0 && state->state <= 23)
			goto top;
	} else if (ret != TBEVENT_SUCCESS) {
		if (state->state >= 0 && state->state < 21)
			state->state = 21;
		else
			state->state++;
		if (state->state >= 0 && state->state <= 23)
			goto top;
	}
	if (state->state >= 0 && state->state > 23) {
		if (state->cbfunc)
			ret = state->cbfunc(state->out.errorcode, state->cbarg,
					state->out.xid);
		free_test_state(state);
		free(state);
		state = NULL;
	}
out:
	if (state)
		state->loopdetect--;
	if (ret == TBEVENT_SUCCESS || ret == TBEVENT_BLOCKDONE ||
			ret == TBEVENT_CALLBACK)
		return ret;
	else
		log_warnx("test: %s", tb_error(ret));
	return TBEVENT_BLOCKDONE;
}