<commit_before>#include "sssl.h"
#include "ssock.h"

#include <assert.h>
#include <string.h>

#define SSSL_NORMAL     0
#define SSSL_CONNECT    1
#define SSSL_CONNECTING 2
#define SSSL_CONNECTED  3
#define SSSL_SHUTDOWN   4
#define SSSL_CLOSE      5

struct sssl {
	SSL_CTX   *ssl_ctx;
	SSL       *ssl;
	BIO       *send_bio;
	BIO       *recv_bio;
	ringbuf_t  send_rb;
	ringbuf_t  recv_rb;
	struct ssock *fd;
	int        state;
};

static int
sssl_write_ssock(struct sssl *self) {
	int w = 0;
	int b = 0;
	int e = 0;
	int l = 4096;
	char buf[4096] = { 0 };
	int nread = BIO_read(self->send_bio, buf, l);
	while (nread > 0) {
		b += nread;
		int nwrite = ssock_writex(self->fd, buf + e, b - e);
		w += nwrite;
		e += nwrite;

		nread = BIO_read(self->send_bio, buf + b, l - b);
	}
	while (b != e) {
		int nwrite = ssock_writex(self->fd, buf + e, b - e);
		w += nwrite;
		e += nwrite;
	}
	return nread;
}

static int
sssl_read_data(struct sssl *self) {
	int r = 0;
	int b = 0;
	int e = 0;
	int l = 4096;
	char buf[4096] = { 0 };
	int nread = SSL_read(self->ssl, buf, l);
	while (nread > 0) {
		b += nread;
		r += nread;

		ssock_datax(self->fd, buf + e, b - e);
		e += nread;

		nread = SSL_read(self->ssl, buf + b, l - b);
	}

	printf("socket %d bytes\r\n", r);
	return 1;
}

static int
sssl_handle_err(struct sssl *self, int code) {
	if (code != 1) {
		int err = SSL_get_error(self->ssl, code);
		if (err == SSL_ERROR_WANT_READ) {
			// ȴ
			printf("want read.\r\n");
		} else if (err == SSL_ERROR_WANT_WRITE) {
			sssl_write_ssock(self);
		} else if (err == SSL_ERROR_SSL) {
			printf("error ssl");
		} else if (err == SSL_ERROR_WANT_CONNECT) {
			printf("error want connect");
		}
	}
	return 1;
}

struct sssl *
	sssl_alloc(struct ssock *fd) {
	SSL_library_init();
	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();
	ERR_load_BIO_strings();

	// ssl ctx
	struct sssl *inst = (struct sssl *)malloc(sizeof(*inst));
	memset(inst, 0, sizeof(*inst));
	inst->ssl_ctx = SSL_CTX_new(SSLv23_client_method());

	// ssl
	inst->ssl = SSL_new(inst->ssl_ctx);

	// bio
	inst->send_bio = BIO_new(BIO_s_mem());
	inst->recv_bio = BIO_new(BIO_s_mem());

	inst->send_rb = ringbuf_new(4096);
	inst->recv_rb = ringbuf_new(4096);

	SSL_set_bio(inst->ssl, inst->recv_bio, inst->send_bio);

	inst->fd = fd;
	inst->state = SSSL_NORMAL;

	return inst;
}

void
sssl_free(struct sssl *self) {
	assert(self->state == SSSL_CLOSE);
	BIO_free(self->send_bio);
	BIO_free(self->recv_bio);

	SSL_free(self->ssl);

	SSL_CTX_free(self->ssl_ctx);
	ERR_free_strings();

	free(self);
}

int
sssl_connect(struct sssl *self) {
	self->state = SSSL_CONNECT;
	SSL_set_connect_state(self->ssl);
	int ret = SSL_connect(self->ssl);

	// һ
	sssl_write_ssock(self);

	if (ret != 1) {
		sssl_handle_err(self, ret);
	}
	return 1;
}

int
sssl_poll(struct sssl *self, const char *buf, int sz) {
	if (sz <= 0) {
		return 0;
	}
	// ȷbufȷ
	assert(buf != NULL && sz > 0);

	int nw = BIO_write(self->recv_bio, buf, sz);
	while (nw < sz) {
		nw = BIO_write(self->recv_bio, buf + nw, sz - nw);
	}

	if (SSSL_CONNECT <= self->state && self->state <= SSSL_CONNECTED) {
		// жhanshakeǷ
		if (!SSL_is_init_finished(self->ssl)) {
			sssl_set_state(self, SSSL_CONNECTING);
			int ret = SSL_do_handshake(self->ssl);
			sssl_write_ssock(self);
			if (ret != 1) {
				sssl_handle_err(self, ret);
				return ret;
			} else {
				printf("openssl handshake success.\r\n");
				sssl_set_state(self, SSSL_CONNECTED);
				//sssl_read_bio(self);<commit_msg>fix write n<commit_after>#include "sssl.h"
#include "ssock.h"

#include <assert.h>
#include <string.h>

#define SSSL_NORMAL     0
#define SSSL_CONNECT    1
#define SSSL_CONNECTING 2
#define SSSL_CONNECTED  3
#define SSSL_SHUTDOWN   4
#define SSSL_CLOSE      5

struct sssl {
	SSL_CTX   *ssl_ctx;
	SSL       *ssl;
	BIO       *send_bio;
	BIO       *recv_bio;
	ringbuf_t  send_rb;
	ringbuf_t  recv_rb;
	struct ssock *fd;
	int        state;
};

static int
sssl_write_ssock(struct sssl *self) {
	int w = 0;
	int b = 0;
	int e = 0;
	int l = 4096;
	char buf[4096] = { 0 };
	int nread = BIO_read(self->send_bio, buf, l);
	while (nread > 0) {
		b += nread;
		int nwrite = ssock_writex(self->fd, buf + e, b - e);
		w += nwrite;
		e += nwrite;

		nread = BIO_read(self->send_bio, buf + b, l - b);
	}
	while (b != e) {
		int nwrite = ssock_writex(self->fd, buf + e, b - e);
		w += nwrite;
		e += nwrite;
	}
	return nread;
}

static int
sssl_read_data(struct sssl *self) {
	int r = 0;
	int b = 0;
	int e = 0;
	int l = 4096;
	char buf[4096] = { 0 };
	int nread = SSL_read(self->ssl, buf, l);
	while (nread > 0) {
		b += nread;
		r += nread;

		ssock_datax(self->fd, buf + e, b - e);
		e += nread;

		nread = SSL_read(self->ssl, buf + b, l - b);
	}

	printf("socket %d bytes\r\n", r);
	return 1;
}

static int
sssl_handle_err(struct sssl *self, int code) {
	if (code != 1) {
		int err = SSL_get_error(self->ssl, code);
		if (err == SSL_ERROR_WANT_READ) {
			// ȴ
			printf("want read.\r\n");
		} else if (err == SSL_ERROR_WANT_WRITE) {
			sssl_write_ssock(self);
		} else if (err == SSL_ERROR_SSL) {
			printf("error ssl");
		} else if (err == SSL_ERROR_WANT_CONNECT) {
			printf("error want connect");
		}
	}
	return 1;
}

struct sssl *
	sssl_alloc(struct ssock *fd) {
	SSL_library_init();
	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();
	ERR_load_BIO_strings();

	// ssl ctx
	struct sssl *inst = (struct sssl *)malloc(sizeof(*inst));
	memset(inst, 0, sizeof(*inst));
	inst->ssl_ctx = SSL_CTX_new(SSLv23_client_method());

	// ssl
	inst->ssl = SSL_new(inst->ssl_ctx);

	// bio
	inst->send_bio = BIO_new(BIO_s_mem());
	inst->recv_bio = BIO_new(BIO_s_mem());

	inst->send_rb = ringbuf_new(4096);
	inst->recv_rb = ringbuf_new(4096);

	SSL_set_bio(inst->ssl, inst->recv_bio, inst->send_bio);

	inst->fd = fd;
	inst->state = SSSL_NORMAL;

	return inst;
}

void
sssl_free(struct sssl *self) {
	assert(self->state == SSSL_CLOSE);
	BIO_free(self->send_bio);
	BIO_free(self->recv_bio);

	SSL_free(self->ssl);

	SSL_CTX_free(self->ssl_ctx);
	ERR_free_strings();

	free(self);
}

int
sssl_connect(struct sssl *self) {
	self->state = SSSL_CONNECT;
	SSL_set_connect_state(self->ssl);
	int ret = SSL_connect(self->ssl);

	// һ
	sssl_write_ssock(self);

	if (ret != 1) {
		sssl_handle_err(self, ret);
	}
	return 1;
}

int
sssl_poll(struct sssl *self, const char *buf, int sz) {
	if (sz <= 0) {
		return 0;
	}
	// ȷbufȷ
	assert(buf != NULL && sz > 0);

	int nw = BIO_write(self->recv_bio, buf, sz);
	while (nw < sz) {
		sz -= nw;
		nw = BIO_write(self->recv_bio, buf + nw, sz);
	}

	if (SSSL_CONNECT <= self->state && self->state <= SSSL_CONNECTED) {
		// жhanshakeǷ
		if (!SSL_is_init_finished(self->ssl)) {
			sssl_set_state(self, SSSL_CONNECTING);
			int ret = SSL_do_handshake(self->ssl);
			sssl_write_ssock(self);
			if (ret != 1) {
				sssl_handle_err(self, ret);
				return ret;
			} else {
				printf("openssl handshake success.\r\n");
				sssl_set_state(self, SSSL_CONNECTED);
				//sssl_read_bio(self);
{'fraction_non_alphanumeric': 0.15928950007162299, 'fraction_numerical': 0.0148975791433892, 'mean_word_length': 3.516170763260026, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2900037', 'n_tokens_mistral': 3260, 'n_tokens_neox': 3036, 'n_words': 670}