bit better sockets
This commit is contained in:
parent
c4d1ffe539
commit
aa08240ec9
4 changed files with 111 additions and 25 deletions
2
http.c
2
http.c
|
|
@ -289,7 +289,7 @@ http_response_t hcliSendRequest(http_client_t *ctx, http_request_t *req) {
|
||||||
goto skopen_error;
|
goto skopen_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->socket = skOpen();
|
ctx->socket = skOpen(SOCK_TCP);
|
||||||
if(ctx->socket == INVALID_SOCKET) {
|
if(ctx->socket == INVALID_SOCKET) {
|
||||||
err("couldn't open socket %s", skGetErrorString());
|
err("couldn't open socket %s", skGetErrorString());
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
||||||
83
socket.c
83
socket.c
|
|
@ -1,6 +1,12 @@
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "tracelog.h"
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// VERY MUCH NOT THREAD SAFE
|
||||||
|
static int initialize_count = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SOCK_WINDOWS
|
#if SOCK_WINDOWS
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
@ -13,8 +19,6 @@ static const char *_win_skGetErrorString();
|
||||||
#define SOCK_CALL(fun) _win_##fun
|
#define SOCK_CALL(fun) _win_##fun
|
||||||
|
|
||||||
#elif SOCK_POSIX
|
#elif SOCK_POSIX
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
@ -33,18 +37,37 @@ static const char *_posix_skGetErrorString();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool skInit() {
|
bool skInit() {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
++initialize_count;
|
||||||
|
#endif
|
||||||
return SOCK_CALL(skInit());
|
return SOCK_CALL(skInit());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skCleanup() {
|
bool skCleanup() {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
--initialize_count;
|
||||||
|
#endif
|
||||||
return SOCK_CALL(skCleanup());
|
return SOCK_CALL(skCleanup());
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t skOpen() {
|
socket_t skOpen(skType type) {
|
||||||
return skOpenPro(AF_INET, SOCK_STREAM, 0);
|
int sock_type;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case SOCK_TCP: sock_type = SOCK_STREAM; break;
|
||||||
|
case SOCK_UDP: sock_type = SOCK_DGRAM; break;
|
||||||
|
default: fatal("skType not recognized: %d", type); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return skOpenPro(AF_INET, sock_type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t skOpenEx(const char *protocol) {
|
socket_t skOpenEx(const char *protocol) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if(initialize_count <= 0) {
|
||||||
|
fatal("skInit has not been called");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
struct protoent *proto = getprotobyname(protocol);
|
struct protoent *proto = getprotobyname(protocol);
|
||||||
if(!proto) {
|
if(!proto) {
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
|
|
@ -53,9 +76,22 @@ socket_t skOpenEx(const char *protocol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t skOpenPro(int af, int type, int protocol) {
|
socket_t skOpenPro(int af, int type, int protocol) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if(initialize_count <= 0) {
|
||||||
|
fatal("skInit has not been called");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return socket(af, type, protocol);
|
return socket(af, type, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sk_addrin_t skAddrinInit(const char *ip, uint16_t port) {
|
||||||
|
sk_addrin_t addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
addr.sin_addr.s_addr = inet_addr(ip);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
bool skClose(socket_t sock) {
|
bool skClose(socket_t sock) {
|
||||||
#if SOCK_WINDOWS
|
#if SOCK_WINDOWS
|
||||||
int error = closesocket(sock);
|
int error = closesocket(sock);
|
||||||
|
|
@ -67,17 +103,17 @@ bool skClose(socket_t sock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skBind(socket_t sock, const char *ip, uint16_t port) {
|
bool skBind(socket_t sock, const char *ip, uint16_t port) {
|
||||||
struct sockaddr_in addr;
|
sk_addrin_t addr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
// TODO use inet_pton instead
|
// TODO use inet_pton instead
|
||||||
addr.sin_addr.s_addr = inet_addr(ip);
|
addr.sin_addr.s_addr = inet_addr(ip);
|
||||||
|
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
return skBindPro(sock, (struct sockaddr *) &addr, sizeof(addr));
|
return skBindPro(sock, (sk_addr_t *) &addr, sizeof(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skBindPro(socket_t sock, const struct sockaddr *name, socket_len_t namelen) {
|
bool skBindPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen) {
|
||||||
return bind(sock, name, namelen) != SOCKET_ERROR;
|
return bind(sock, name, namelen) != SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,12 +126,12 @@ bool skListenPro(socket_t sock, int backlog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t skAccept(socket_t sock) {
|
socket_t skAccept(socket_t sock) {
|
||||||
struct sockaddr_in addr;
|
sk_addrin_t addr;
|
||||||
socket_len_t addr_size = (socket_len_t)sizeof(addr);
|
socket_len_t addr_size = (socket_len_t)sizeof(addr);
|
||||||
return skAcceptPro(sock, (struct sockaddr *) &addr, &addr_size);
|
return skAcceptPro(sock, (sk_addr_t *) &addr, &addr_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t skAcceptPro(socket_t sock, struct sockaddr *addr, socket_len_t *addrlen) {
|
socket_t skAcceptPro(socket_t sock, sk_addr_t *addr, socket_len_t *addrlen) {
|
||||||
return accept(sock, addr, addrlen);
|
return accept(sock, addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,26 +144,34 @@ bool skConnect(socket_t sock, const char *server, unsigned short server_port) {
|
||||||
address = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]);
|
address = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
sk_addrin_t addr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_addr.s_addr = inet_addr(address);
|
addr.sin_addr.s_addr = inet_addr(address);
|
||||||
addr.sin_port = htons(server_port);
|
addr.sin_port = htons(server_port);
|
||||||
|
|
||||||
return skConnectPro(sock, (struct sockaddr *) &addr, sizeof(addr));
|
return skConnectPro(sock, (sk_addr_t *) &addr, sizeof(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skConnectPro(socket_t sock, const struct sockaddr *name, socket_len_t namelen) {
|
bool skConnectPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen) {
|
||||||
return connect(sock, name, namelen) != SOCKET_ERROR;
|
return connect(sock, name, namelen) != SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int skSend(socket_t sock, char *buf, int len) {
|
int skSend(socket_t sock, const char *buf, int len) {
|
||||||
return skSendPro(sock, buf, len, 0);
|
return skSendPro(sock, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int skSendPro(socket_t sock, char *buf, int len, int flags) {
|
int skSendPro(socket_t sock, const char *buf, int len, int flags) {
|
||||||
return send(sock, buf, len, flags);
|
return send(sock, buf, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int skSendTo(socket_t sock, const char *buf, int len, const sk_addrin_t *to) {
|
||||||
|
return skSendToPro(sock, buf, len, 0, (sk_addr_t*) to, sizeof(sk_addrin_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
int skSendToPro(socket_t sock, const char *buf, int len, int flags, const sk_addr_t *to, int tolen) {
|
||||||
|
return sendto(sock, buf, len, flags, to, tolen);
|
||||||
|
}
|
||||||
|
|
||||||
int skReceive(socket_t sock, char *buf, int len) {
|
int skReceive(socket_t sock, char *buf, int len) {
|
||||||
return skReceivePro(sock, buf, len, 0);
|
return skReceivePro(sock, buf, len, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +180,15 @@ int skReceivePro(socket_t sock, char *buf, int len, int flags) {
|
||||||
return recv(sock, buf, len, flags);
|
return recv(sock, buf, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int skReceiveFrom(socket_t sock, char *buf, int len, sk_addrin_t *from) {
|
||||||
|
int fromlen = sizeof(sk_addr_t);
|
||||||
|
return skReceiveFromPro(sock, buf, len, 0, (sk_addr_t*)from, &fromlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int skReceiveFromPro(socket_t sock, char *buf, int len, int flags, sk_addr_t *from, int *fromlen) {
|
||||||
|
return recvfrom(sock, buf, len, flags, from, fromlen);
|
||||||
|
}
|
||||||
|
|
||||||
bool skIsValid(socket_t sock) {
|
bool skIsValid(socket_t sock) {
|
||||||
return sock != INVALID_SOCKET;
|
return sock != INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
socket.h
47
socket.h
|
|
@ -13,27 +13,38 @@ extern "C" {
|
||||||
#define SOCK_POSIX 1
|
#define SOCK_POSIX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct sockaddr;
|
|
||||||
|
|
||||||
#if SOCK_WINDOWS
|
#if SOCK_WINDOWS
|
||||||
|
#pragma warning(disable:4996) // _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
typedef SOCKET socket_t;
|
typedef SOCKET socket_t;
|
||||||
typedef int socket_len_t;
|
typedef int socket_len_t;
|
||||||
#elif SOCK_POSIX
|
#elif SOCK_POSIX
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
typedef int socket_t;
|
typedef int socket_t;
|
||||||
typedef uint32_t socket_len_t;
|
typedef uint32_t socket_len_t;
|
||||||
#define INVALID_SOCKET (-1)
|
#define INVALID_SOCKET (-1)
|
||||||
#define SOCKET_ERROR (-1)
|
#define SOCKET_ERROR (-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct sockaddr sk_addr_t;
|
||||||
|
typedef struct sockaddr_in sk_addrin_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SOCK_TCP,
|
||||||
|
SOCK_UDP,
|
||||||
|
} skType;
|
||||||
|
|
||||||
|
// == RAW SOCKETS ==========================================
|
||||||
|
|
||||||
// Initialize sockets, returns true on success
|
// Initialize sockets, returns true on success
|
||||||
bool skInit(void);
|
bool skInit(void);
|
||||||
// Terminates sockets, returns true on success
|
// Terminates sockets, returns true on success
|
||||||
bool skCleanup(void);
|
bool skCleanup(void);
|
||||||
|
|
||||||
// Opens a socket, check socket_t with skValid
|
// Opens a socket, check socket_t with skValid
|
||||||
socket_t skOpen(void);
|
socket_t skOpen(skType type);
|
||||||
// Opens a socket using 'protocol', options are
|
// Opens a socket using 'protocol', options are
|
||||||
// ip, icmp, ggp, tcp, egp, pup, udp, hmp, xns-idp, rdp
|
// ip, icmp, ggp, tcp, egp, pup, udp, hmp, xns-idp, rdp
|
||||||
// check socket_t with skValid
|
// check socket_t with skValid
|
||||||
|
|
@ -41,13 +52,16 @@ socket_t skOpenEx(const char *protocol);
|
||||||
// Opens a socket, check socket_t with skValid
|
// Opens a socket, check socket_t with skValid
|
||||||
socket_t skOpenPro(int af, int type, int protocol);
|
socket_t skOpenPro(int af, int type, int protocol);
|
||||||
|
|
||||||
|
// Fill out a sk_addrin_t structure with "ip" and "port"
|
||||||
|
sk_addrin_t skAddrinInit(const char *ip, uint16_t port);
|
||||||
|
|
||||||
// Closes a socket, returns true on success
|
// Closes a socket, returns true on success
|
||||||
bool skClose(socket_t sock);
|
bool skClose(socket_t sock);
|
||||||
|
|
||||||
// Associate a local address with a socket
|
// Associate a local address with a socket
|
||||||
bool skBind(socket_t sock, const char *ip, uint16_t port);
|
bool skBind(socket_t sock, const char *ip, uint16_t port);
|
||||||
// Associate a local address with a socket
|
// Associate a local address with a socket
|
||||||
bool skBindPro(socket_t sock, const struct sockaddr *name, socket_len_t namelen);
|
bool skBindPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen);
|
||||||
|
|
||||||
// Place a socket in a state in which it is listening for an incoming connection
|
// Place a socket in a state in which it is listening for an incoming connection
|
||||||
bool skListen(socket_t sock);
|
bool skListen(socket_t sock);
|
||||||
|
|
@ -57,21 +71,29 @@ bool skListenPro(socket_t sock, int backlog);
|
||||||
// Permits an incoming connection attempt on a socket
|
// Permits an incoming connection attempt on a socket
|
||||||
socket_t skAccept(socket_t sock);
|
socket_t skAccept(socket_t sock);
|
||||||
// Permits an incoming connection attempt on a socket
|
// Permits an incoming connection attempt on a socket
|
||||||
socket_t skAcceptPro(socket_t sock, struct sockaddr *addr, socket_len_t *addrlen);
|
socket_t skAcceptPro(socket_t sock, sk_addr_t *addr, socket_len_t *addrlen);
|
||||||
|
|
||||||
// Connects to a server (e.g. "127.0.0.1" or "google.com") with a port(e.g. 1234), returns true on success
|
// Connects to a server (e.g. "127.0.0.1" or "google.com") with a port(e.g. 1234), returns true on success
|
||||||
bool skConnect(socket_t sock, const char *server, unsigned short server_port);
|
bool skConnect(socket_t sock, const char *server, unsigned short server_port);
|
||||||
// Connects to a server, returns true on success
|
// Connects to a server, returns true on success
|
||||||
bool skConnectPro(socket_t sock, const struct sockaddr *name, socket_len_t namelen);
|
bool skConnectPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen);
|
||||||
|
|
||||||
// Sends data on a socket, returns true on success
|
// Sends data on a socket, returns true on success
|
||||||
int skSend(socket_t sock, char *buf, int len);
|
int skSend(socket_t sock, const char *buf, int len);
|
||||||
// Sends data on a socket, returns true on success
|
// Sends data on a socket, returns true on success
|
||||||
int skSendPro(socket_t sock, char *buf, int len, int flags);
|
int skSendPro(socket_t sock, const char *buf, int len, int flags);
|
||||||
|
// Sends data to a specific destination
|
||||||
|
int skSendTo(socket_t sock, const char *buf, int len, const sk_addrin_t *to);
|
||||||
|
// Sends data to a specific destination
|
||||||
|
int skSendToPro(socket_t sock, const char *buf, int len, int flags, const sk_addr_t *to, int tolen);
|
||||||
// Receives data from a socket, returns byte count on success, 0 on connection close or -1 on error
|
// Receives data from a socket, returns byte count on success, 0 on connection close or -1 on error
|
||||||
int skReceive(socket_t sock, char *buf, int len);
|
int skReceive(socket_t sock, char *buf, int len);
|
||||||
// Sends data on a socket, returns true on success
|
// Receives data from a socket, returns byte count on success, 0 on connection close or -1 on error
|
||||||
int skReceivePro(socket_t sock, char *buf, int len, int flags);
|
int skReceivePro(socket_t sock, char *buf, int len, int flags);
|
||||||
|
// Receives a datagram and stores the source address.
|
||||||
|
int skReceiveFrom(socket_t sock, char *buf, int len, sk_addrin_t *from);
|
||||||
|
// Receives a datagram and stores the source address.
|
||||||
|
int skReceiveFromPro(socket_t sock, char *buf, int len, int flags, sk_addr_t *from, int *fromlen);
|
||||||
|
|
||||||
// Checks that a opened socket is valid, returns true on success
|
// Checks that a opened socket is valid, returns true on success
|
||||||
bool skIsValid(socket_t sock);
|
bool skIsValid(socket_t sock);
|
||||||
|
|
@ -81,6 +103,13 @@ int skGetError(void);
|
||||||
// Returns a human-readable string from a skGetError
|
// Returns a human-readable string from a skGetError
|
||||||
const char *skGetErrorString(void);
|
const char *skGetErrorString(void);
|
||||||
|
|
||||||
|
// == UDP SOCKETS ==========================================
|
||||||
|
|
||||||
|
typedef socket_t udpsock_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma warning(disable:4996) // _CRT_SECURE_NO_WARNINGS.
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TLOG_VS
|
#ifdef TLOG_VS
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef TLOG_NO_COLOURS
|
#ifndef TLOG_NO_COLOURS
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue