Permalink
Browse files

port to MacOS/Homebrew

  • Loading branch information...
kvic-z committed Oct 31, 2018
1 parent d266a6b commit 0fdf1f529c733b7dd0b2bef4a023335497397492
Showing with 66 additions and 35 deletions.
  1. +2 −2 Makefile.am
  2. +10 −5 certs.c
  3. +31 −17 pixelserv.c
  4. +14 −6 socket_handler.c
  5. +9 −5 util.h
@@ -1,6 +1,6 @@
bin_PROGRAMS = pixelserv-tls
man1_MANS = pixelserv-tls.1
pixelserv_tls_CFLAGS = -DDROP_ROOT -DIF_MODE -DDEFAULT_PEM_PATH=\"/var/cache/pixelserv\"
pixelserv_tls_CFLAGS += -O3 -s -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing
pixelserv_tls_LDFLAGS = -Wl,--gc-sections $(EXTRA_LDFLAGS)
pixelserv_tls_CFLAGS += -O3 -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing $(EXTRA_CFLAGS)
pixelserv_tls_LDFLAGS = $(EXTRA_LDFLAGS)
pixelserv_tls_SOURCES = pixelserv.c socket_handler.c certs.c util.c logger.c
15 certs.c
@@ -4,7 +4,6 @@
#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <malloc.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
@@ -23,6 +22,10 @@
#include "logger.h"
#include "util.h"

#if defined(__GLIBC__) && !defined(__UCLIBC__)
# include <malloc.h>
#endif

static pthread_mutex_t *locks;
static SSL_CTX *g_sslctx;

@@ -143,7 +146,7 @@ static int cmp_sslctx_certname(const void *k, const void *p)
void sslctx_tbl_load(const char* pem_dir, const STACK_OF(X509_INFO) *cachain)
{
FILE *fp;
char *fname, *line;
char *fname = NULL, *line;
if ((line = malloc(PIXELSERV_MAX_PATH)) == NULL || (fname = malloc(PIXELSERV_MAX_PATH)) == NULL) {
log_msg(LGG_ERR, "%s: failed to allocate memory", __FUNCTION__);
goto quit_load;
@@ -741,9 +744,11 @@ static int tls_servername_cb(SSL *ssl, int *ad, void *arg) {
if ((fd = open(PIXEL_CERT_PIPE, O_WRONLY)) < 0)
log_msg(LGG_ERR, "%s: failed to open pipe: %s", __FUNCTION__, strerror(errno));
else {
/* reuse full_pem_path as scratchpad */
strcpy(full_pem_path, pem_file);
/* reuse full_pem_path as scratchpad. use memcpy in place of strcpy.
strcpy overlapped buffer is not portable. */
memcpy(full_pem_path, pem_file, strlen(pem_file) + 1);
strcat(full_pem_path, ":");

if (write(fd, full_pem_path, strlen(full_pem_path)) < 0)
log_msg(LGG_ERR, "%s: failed to write pipe: %s", __FUNCTION__, strerror(errno));
close(fd);
@@ -953,7 +958,7 @@ char* read_tls_early_data(SSL *ssl)
void run_benchmark(const cert_tlstor_t *ct, const char *cert)
{
int c, d;
char *cert_file, *domain;
char *cert_file = NULL, *domain;
struct stat st;
struct timespec tm;
float r_tm0, g_tm0, tm1;
@@ -12,8 +12,9 @@
#ifdef TEST
#include <arpa/inet.h>
#endif
#ifdef linux
#include <linux/version.h>
#include <malloc.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/resource.h>
@@ -26,6 +27,14 @@
#include "socket_handler.h"
#include "util.h"

#if defined(__GLIBC__) && !defined(__UCLIBC__)
# include <malloc.h>
#endif

#ifndef SO_BINDTODEVICE
# define SO_BINDTODEVICE IP_RECVIF
#endif

#define PAGE_SIZE 4096
#define THREAD_STACK_SIZE 9*PAGE_SIZE
#define TCP_FASTOPEN_QLEN 25
@@ -392,12 +401,14 @@ int main (int argc, char* argv[])

if ( ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) < 1)
|| setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int))
|| setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &(int){ 1 }, sizeof(int))
|| setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &(int){ 1 }, sizeof(int))
#ifdef IF_MODE
|| (use_if && (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname))))
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) || ENABLE_TCP_FASTOPEN
|| setsockopt(sockfd, SOL_TCP, TCP_FASTOPEN, &(int){ TCP_FASTOPEN_QLEN }, sizeof(int))
#ifdef linux
# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) || ENABLE_TCP_FASTOPEN
|| setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN, &(int){ TCP_FASTOPEN_QLEN }, sizeof(int))
# endif
#endif
|| bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen)
|| listen(sockfd, BACKLOG)
@@ -693,6 +704,22 @@ int main (int argc, char* argv[])
continue;
}

/* Set socket to blocking explicitly.
On Linux, file descriptor attributes are not inherited from parent.
On macOS, the attributes are inherited from parent. */
int flags;
if ((flags = fcntl(new_fd, F_GETFL, 0)) < 0 || fcntl(new_fd, F_SETFL, flags & (~O_NONBLOCK)) < 0)
log_msg(LGG_WARNING, "%s fail to set new_fd to blocking", __FUNCTION__);

/* Set socket to TCP_NODELAY explicitly.
On Linux, socket options are not inherited from parent.
On macOS, the attributes are not inherited from parent. */
if (setsockopt(new_fd, IPPROTO_TCP, TCP_NODELAY, &(int){ 1 }, sizeof(int)) ||
setsockopt(new_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&(struct timeval){ 0, 60000 },
sizeof(struct timeval))) {
log_msg(LGG_WARNING, "%s setsockopt() failed on new_fd", __FUNCTION__);
}

conn_tlstor->new_fd = new_fd;
conn_tlstor->ssl = NULL;
conn_tlstor->allow_admin = (!admin_port) ? 1 : 0;
@@ -714,14 +741,6 @@ int main (int argc, char* argv[])
if (ssl_port == admin_port)
conn_tlstor->allow_admin = 1;

/* TCP_NODELAY is not inherited from acceptance */
if (setsockopt(new_fd, SOL_TCP, TCP_NODELAY, &(int){ 1 }, sizeof(int)) ||
setsockopt(new_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&(struct timeval){ 0, 60000 },
sizeof(struct timeval))) {
log_msg(LOG_CRIT, "Abort: %m - new_fd setsockopt");
exit(EXIT_FAILURE);
}

#ifdef TLS1_3_VERSION
SSL_CTX_set_client_hello_cb(sslctx, tls_clienthello_cb, t);
conn_tlstor->early_data = read_tls_early_data(ssl);
@@ -775,11 +794,6 @@ int main (int argc, char* argv[])
log_msg(LGG_WARNING, "handshake failed: unknown cert. client %s:%s server %s",
ip_buf, port_buf, t->servername);
break;
case SSL_R_INAPPROPRIATE_FALLBACK:
if (t->servername == NULL) {
t->status = SSL_MISS;
break;
}
case SSL_R_PARSE_TLSEXT:
if (t->status == SSL_MISS)
break;
@@ -336,6 +336,14 @@ char* strstr_last(const char* const str1, const char* const str2) {
return 0;
}

/* strstr behavior undefined if one or more parameter is null.
Not portable as MacOS default to crash. */
char* strstr_first(const char* const str1, const char* const str2) {
if (!str1) return NULL;
if (!str2) return (char*)str1;
return strstr(str1, str2);
}

char from_hex(const char ch) {
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}
@@ -523,7 +531,7 @@ static int write_socket(int fd, const char *msg, int msg_len, SSL *ssl, char **e
rv = ssl_write(ssl, msg, msg_len);
} else {
/* a blocking call, so zero should not be returned */
rv = send(fd, msg, msg_len, MSG_NOSIGNAL);
rv = send(fd, msg, msg_len, 0);
}
return rv;
}
@@ -667,7 +675,7 @@ void* conn_handler( void *ptr )
#ifdef HEX_DUMP
hex_dump(buf, rv);
#endif
char *body = strstr(buf, "\r\n\r\n");
char *body = strstr_first(buf, "\r\n\r\n");
int body_len = (body) ? (rv + buf - body) : 0;
char *req = strtok_r(buf, "\r\n", &bufptr);
if (log_verbose >= LGG_INFO) {
@@ -680,7 +688,7 @@ void* conn_handler( void *ptr )
}
strcpy(req_url, req);
/* locate and copy Host */
char *tmph = strstr(bufptr, "Host: "); // e.g. "Host: abc.com"
char *tmph = strstr_first(bufptr, "Host: "); // e.g. "Host: abc.com"
if (tmph) {
host[HOST_LEN_MAX] = '\0';
strncpy(host, tmph + 6 /* strlen("Host: ") */, HOST_LEN_MAX);
@@ -691,7 +699,7 @@ void* conn_handler( void *ptr )
}
/* CORS */
char *orig_hdr;
orig_hdr = strstr(bufptr, "Origin: ");
orig_hdr = strstr_first(bufptr, "Origin: ");
if (orig_hdr) {
cors_origin = malloc(CORS_ORIGIN_LEN_MAX);
strncpy(cors_origin, orig_hdr + 8, CORS_ORIGIN_LEN_MAX);
@@ -717,7 +725,7 @@ void* conn_handler( void *ptr )
int length = 0;
int post_buf_size = 0;
int wait_cnt = 0;
char *h = strstr(bufptr, "Content-Length:");
char *h = strstr_first(bufptr, "Content-Length:");

wait_cnt = MAX_HTTP_POST_WAIT / GLOBAL(g, select_timeout);
if (wait_cnt < 1) wait_cnt = 1;
@@ -896,7 +904,7 @@ void* conn_handler( void *ptr )
for (tok = strtok_r(NULL, "\r\n", &bufptr); tok; tok = strtok_r(NULL, "\r\n", &bufptr)) {
char *hkey = strtok(tok, ":");
char *hvalue = strtok(NULL, "\r\n");
if (strstr(hkey, "Referer") && strstr(hvalue, url)) {
if (strstr_first(hkey, "Referer") && strstr_first(hvalue, url)) {
url = NULL;
TESTPRINT("Not redirecting likely callback URL: %s:%s\n", hkey, hvalue);
break;
14 util.h
@@ -17,7 +17,9 @@
#include <unistd.h> // close(), setuid(), TEMP_FAILURE_RETRY, fork()
#include <time.h> // struct timespec, clock_gettime(), difftime()
#include <arpa/inet.h>
#include <linux/version.h>
#ifdef linux
# include <linux/version.h>
#endif
#include <openssl/ssl.h>

// preprocessor defines
@@ -55,10 +57,12 @@
__result; }))
#endif

# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) || ENABLE_TCP_FASTOPEN
# define FEAT_TFO " tfo"
# else
# define FEAT_TFO
# define FEAT_TFO
# ifdef linux
# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) || ENABLE_TCP_FASTOPEN
# undef FEAT_TFO
# define FEAT_TFO " tfo"
# endif
# endif
# ifdef TLS1_3_VERSION
# define FEAT_TLS1_3 " tls1_3"

0 comments on commit 0fdf1f5

Please sign in to comment.