1
0
Fork 0
Univerxel/deps/picoquic/picosocks.h

247 lines
6.6 KiB
C

/*
* Author: Christian Huitema
* Copyright (c) 2017, Private Octopus, Inc.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Private Octopus, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PICOSOCKS_H
#define PICOSOCKS_H
#ifdef _WINDOWS
/* clang-format off */
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Ws2def.h>
#include <WinSock2.h>
#include <ws2ipdef.h>
#include <Mswsock.h>
#include <assert.h>
#include <iphlpapi.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <ws2tcpip.h>
#ifndef SOCKET_TYPE
#define SOCKET_TYPE SOCKET
#endif
#ifndef SOCKET_CLOSE
#define SOCKET_CLOSE(x) closesocket(x)
#endif
#ifndef WSA_START_DATA
#define WSA_START_DATA WSADATA
#endif
#ifndef WSA_START
#define WSA_START(x, y) WSAStartup((x), (y))
#endif
#ifndef WSA_LAST_ERROR
#define WSA_LAST_ERROR(x) WSAGetLastError()
#endif
#ifndef socklen_t
#define socklen_t int
#endif
/* clang-format on */
#else /* Linux */
#include "getopt.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef __USE_XOPEN2K
#define __USE_XOPEN2K
#endif
#ifndef __USE_POSIX
#define __USE_POSIX
#endif
#ifndef __USE_GNU
#define __USE_GNU
#endif
#ifndef __APPLE_USE_RFC_3542
#define __APPLE_USE_RFC_3542 /* IPV6_PKTINFO */
#endif
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/select.h>
#ifndef SOCKET_TYPE
#define SOCKET_TYPE int
#endif
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif
#ifndef SOCKET_CLOSE
#define SOCKET_CLOSE(x) close(x)
#endif
#ifndef WSA_LAST_ERROR
#define WSA_LAST_ERROR(x) ((long)(x))
#endif
#ifndef IPV6_RECVPKTINFO
#define IPV6_RECVPKTINFO IPV6_PKTINFO /* Cygwin */
#endif
#endif
#define PICOQUIC_ECN_ECT_0 0x02
#define PICOQUIC_ECN_ECT_1 0x01
#define PICOQUIC_ECN_CE 0x03
#include "picoquic.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WINDOWS
typedef struct st_picoquic_recvmsg_async_ctx_t {
WSAOVERLAPPED overlap;
LPFN_WSARECVMSG WSARecvMsg;
LPFN_WSASENDMSG WSASendMsg;
WSABUF dataBuf;
WSAMSG msg;
char cmsg_buffer[1024];
size_t recv_buffer_size;
uint8_t* recv_buffer;
struct sockaddr_storage addr_from;
struct sockaddr_storage addr_dest;
socklen_t from_length;
socklen_t dest_length;
SOCKET_TYPE fd;
int dest_if;
unsigned char received_ecn;
size_t udp_coalesced_size;
int nb_immediate_receive;
int bytes_recv;
unsigned int is_started : 1;
unsigned int supports_udp_send_coalesced : 1;
unsigned int supports_udp_recv_coalesced : 1;
} picoquic_recvmsg_async_ctx_t;
//
// Not yet available in the SDK. When available this code can be removed.
//
#ifndef UDP_SEND_MSG_SIZE
#define UDP_SEND_MSG_SIZE 2
#endif
#ifndef UDP_RECV_MAX_COALESCED_SIZE
#define UDP_RECV_MAX_COALESCED_SIZE 3
#endif
#ifndef UDP_COALESCED_INFO
#define UDP_COALESCED_INFO 3
#endif
picoquic_recvmsg_async_ctx_t * picoquic_create_async_socket(int af, int recv_coalesced, int send_coalesced);
void picoquic_delete_async_socket(picoquic_recvmsg_async_ctx_t * ctx);
int picoquic_recvmsg_async_start(picoquic_recvmsg_async_ctx_t * ctx);
int picoquic_recvmsg_async_finish(picoquic_recvmsg_async_ctx_t * ctx);
#endif
#define PICOQUIC_NB_SERVER_SOCKETS 2
typedef struct st_picoquic_server_sockets_t {
SOCKET_TYPE s_socket[PICOQUIC_NB_SERVER_SOCKETS];
} picoquic_server_sockets_t;
int picoquic_bind_to_port(SOCKET_TYPE fd, int af, int port);
int picoquic_get_local_address(SOCKET_TYPE sd, struct sockaddr_storage * addr);
SOCKET_TYPE picoquic_open_client_socket(int af);
int picoquic_open_server_sockets(picoquic_server_sockets_t* sockets, int port);
void picoquic_close_server_sockets(picoquic_server_sockets_t* sockets);
int picoquic_socket_set_pkt_info(SOCKET_TYPE sd, int af);
int picoquic_socket_set_ecn_options(SOCKET_TYPE sd, int af, int * recv_set, int * send_set);
int picoquic_select(SOCKET_TYPE* sockets, int nb_sockets,
struct sockaddr_storage* addr_from,
struct sockaddr_storage* addr_dest,
int* dest_if,
unsigned char * received_ecn,
uint8_t* buffer, int buffer_max,
int64_t delta_t,
uint64_t* current_time);
int picoquic_select_ex(SOCKET_TYPE* sockets,
int nb_sockets,
struct sockaddr_storage* addr_from,
struct sockaddr_storage* addr_dest,
int* dest_if,
unsigned char* received_ecn,
uint8_t* buffer, int buffer_max,
int64_t delta_t,
int* socket_rank,
uint64_t* current_time);
int picoquic_send_through_socket(
SOCKET_TYPE fd,
struct sockaddr* addr_dest,
struct sockaddr* addr_from, int from_if,
const char* bytes, int length, int* sock_err);
int picoquic_send_through_server_sockets(
picoquic_server_sockets_t* sockets,
struct sockaddr* addr_dest,
struct sockaddr* addr_from, int from_if,
const char* bytes, int length, int * sock_err);
int picoquic_get_server_address(const char* ip_address_text, int server_port,
struct sockaddr_storage* server_address,
int* is_name);
/* Wireshark needs the session keys in order to decrypt and analyze packets.
* In Unix and Windows, Wireshark reads these keys from a file. The name
* of the file is passed in the environment variable SSLKEYLOGFILE,
* which is accessed through system dependent API.
*/
void picoquic_set_key_log_file_from_env(picoquic_quic_t* quic);
/* Utility functions for implementing async sockets
*/
void picoquic_socks_cmsg_parse(
void* vmsg,
struct sockaddr_storage* addr_dest,
int* dest_if,
unsigned char* received_ecn,
size_t* udp_coalesced_size);
void picoquic_socks_cmsg_format(
void* vmsg,
size_t message_length,
size_t send_msg_size,
struct sockaddr* addr_from,
int dest_if);
#ifdef __cplusplus
}
#endif
#endif