예제 #1
0
// tries to read exactly one line, until '\n', then overwrites the \n with \0
// bytesread contains the number of bytes read till \n was encountered
// (so 0 in case \n was the first char).
// returns RS_E_OUT_OF_BUFFER if the line doesnt fit into the buffer.
int rocksock_readline(rocksock* sock, char* buffer, size_t bufsize, size_t* bytesread) {
	// TODO: make more efficient by peeking into the buffer (Flag MSG_PEEK to recv), instead of reading byte by byte
	// would need a different approach for ssl though.
	if (!sock) return RS_E_NULL;
	if (!buffer || !bufsize || !bytesread)
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_NULL,
		                         ROCKSOCK_FILENAME, __LINE__);
	char* ptr = buffer;
	size_t bytesread2 = 0;
	int ret;
	*bytesread = 0;
	while(*bytesread < bufsize) {
		ret = rocksock_recv(sock, ptr, 1, 1, &bytesread2);
		if(ret || !bytesread2) return ret;
		*bytesread += bytesread2;
		if(ptr > buffer + bufsize)
			break;
		if(*bytesread > bufsize) {
			*bytesread = bufsize;
			break;
		}
		if(*ptr == '\n') {
			*ptr = 0;
			*bytesread -= 1;
			return 0;
		}
		ptr++;
	}
	return rocksock_seterror(sock, RS_ET_OWN, RS_E_OUT_OF_BUFFER,
	                         ROCKSOCK_FILENAME, __LINE__);
}
예제 #2
0
int rocksock_ssl_peek(rocksock* sock, int *result) {
        char buf[4];
	int ret;
	ret = SSL_peek(sock->ssl, buf, 1);
	if(ret >= 0) *result = 1;
	else {
		ret = SSL_get_error(sock->ssl, ret);
		if(ret == SSL_ERROR_WANT_READ)
			return rocksock_seterror(sock, RS_ET_OWN, RS_E_HIT_READTIMEOUT, ROCKSOCK_FILENAME, __LINE__);
		return rocksock_seterror(sock, RS_ET_SSL, ret, ROCKSOCK_FILENAME, __LINE__);
        }
	return rocksock_seterror(sock, RS_ET_OWN, 0, NULL, 0);
}
예제 #3
0
int rocksock_ssl_connect_fd(rocksock* sock) {
	sock->sslctx = SSL_CTX_new(SSLv23_client_method());
	if (!sock->sslctx) {
		ERR_print_errors_fp(stderr);
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_SSL_GENERIC, ROCKSOCK_FILENAME, __LINE__);
	}
	sock->ssl = SSL_new(sock->sslctx);
	if (!sock->ssl) {
		ERR_print_errors_fp(stderr);
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_SSL_GENERIC, ROCKSOCK_FILENAME, __LINE__);
	}
	SSL_set_fd(sock->ssl, sock->socket);
	int ret = SSL_connect(sock->ssl);
	if(ret != 1) {
		if((ret = SSL_get_error(sock->ssl, ret)) == SSL_ERROR_WANT_READ)
			return rocksock_seterror(sock, RS_ET_OWN, RS_E_HIT_CONNECTTIMEOUT, ROCKSOCK_FILENAME, __LINE__);
		//ERR_print_errors_fp(stderr);
		//printf("%dxxx\n", SSL_get_error(sock->ssl, ret));
		return rocksock_seterror(sock, RS_ET_SSL, ret, ROCKSOCK_FILENAME, __LINE__);
	}
	return 0;
}
예제 #4
0
int rocksock_add_proxy(rocksock* sock, rs_proxyType proxytype, const char* host, unsigned short port, const char* username, const char* password) {
	rs_proxy* prx;
	if (!sock)
		return RS_E_NULL;
	if(!host)
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_NULL, ROCKSOCK_FILENAME, __LINE__);
	if(proxytype == RS_PT_SOCKS4 && (username || password))
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_SOCKS4_NOAUTH, ROCKSOCK_FILENAME, __LINE__);
	if(proxytype == RS_PT_SOCKS5 && ((username && strlen(username) > 255) || (password && strlen(password) > 255)))
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_SOCKS5_AUTH_EXCEEDSIZE, ROCKSOCK_FILENAME, __LINE__);
	if(!sock->proxies)
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_NO_PROXYSTORAGE, ROCKSOCK_FILENAME, __LINE__);
	size_t l = strlen(host);
	if(l > 255)
		return rocksock_seterror(sock, RS_ET_OWN, RS_E_HOSTNAME_TOO_LONG, ROCKSOCK_FILENAME, __LINE__);
	sock->lastproxy++;
	prx = &sock->proxies[sock->lastproxy];
	prx->hostinfo.port = port;
	prx->proxytype = proxytype;
	memcpy(prx->hostinfo.host, host, l+1);
	memcpy(prx->username, username?username:"", username?strlen(username)+1:1);
	memcpy(prx->password, password?password:"", password?strlen(password)+1:1);
	return rocksock_seterror(sock, RS_ET_OWN, 0, NULL, 0);
}