00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef NS_SKELETON_HEADER_INCLUDED
00020 #define NS_SKELETON_HEADER_INCLUDED
00021
00022 #define NS_SKELETON_VERSION "2.1.0"
00023
00024 #undef UNICODE // Use ANSI WinAPI functions
00025 #undef _UNICODE // Use multibyte encoding on Windows
00026 #define _MBCS // Use multibyte encoding on Windows
00027 #define _INTEGRAL_MAX_BITS 64 // Enable _stati64() on Windows
00028 #define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005+
00029 #undef WIN32_LEAN_AND_MEAN // Let windows.h always include winsock2.h
00030 #define _XOPEN_SOURCE 600 // For flockfile() on Linux
00031 #define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
00032 #define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
00033 #ifndef _LARGEFILE_SOURCE
00034 #define _LARGEFILE_SOURCE // Enable fseeko() and ftello() functions
00035 #endif
00036 #define _FILE_OFFSET_BITS 64 // Enable 64-bit file offsets
00037
00038 #ifdef _MSC_VER
00039 #pragma warning (disable : 4127) // FD_SET() emits warning, disable it
00040 #pragma warning (disable : 4204) // missing c99 support
00041 #endif
00042
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <assert.h>
00046 #include <ctype.h>
00047 #include <errno.h>
00048 #include <fcntl.h>
00049 #include <stdarg.h>
00050 #include <stddef.h>
00051 #include <stdio.h>
00052 #include <stdlib.h>
00053 #include <string.h>
00054 #include <time.h>
00055 #include <signal.h>
00056
00057 #ifdef _WIN32
00058 #ifdef _MSC_VER
00059 #pragma comment(lib, "ws2_32.lib") // Linking with winsock library
00060 #endif
00061 #include <windows.h>
00062 #include <process.h>
00063 #ifndef EINPROGRESS
00064 #define EINPROGRESS WSAEINPROGRESS
00065 #endif
00066 #ifndef EWOULDBLOCK
00067 #define EWOULDBLOCK WSAEWOULDBLOCK
00068 #endif
00069 #ifndef __func__
00070 #define STRX(x) #x
00071 #define STR(x) STRX(x)
00072 #define __func__ __FILE__ ":" STR(__LINE__)
00073 #endif
00074 #ifndef va_copy
00075 #define va_copy(x,y) x = y
00076 #endif // MINGW #defines va_copy
00077 #define snprintf _snprintf
00078 #define vsnprintf _vsnprintf
00079 #define sleep(x) Sleep((x) * 1000)
00080 #define to64(x) _atoi64(x)
00081 typedef int socklen_t;
00082 typedef unsigned char uint8_t;
00083 typedef unsigned int uint32_t;
00084 typedef unsigned short uint16_t;
00085 typedef unsigned __int64 uint64_t;
00086 typedef __int64 int64_t;
00087 typedef SOCKET sock_t;
00088 typedef struct _stati64 ns_stat_t;
00089 #ifndef S_ISDIR
00090 #define S_ISDIR(x) ((x) & _S_IFDIR)
00091 #endif
00092 #else
00093 #include <errno.h>
00094 #include <fcntl.h>
00095 #include <netdb.h>
00096 #include <pthread.h>
00097 #include <stdarg.h>
00098 #include <unistd.h>
00099 #include <arpa/inet.h>
00100 #include <netinet/in.h>
00101 #include <sys/socket.h>
00102 #include <sys/select.h>
00103 #define closesocket(x) close(x)
00104 #define __cdecl
00105 #define INVALID_SOCKET (-1)
00106 #define to64(x) strtoll(x, NULL, 10)
00107 typedef int sock_t;
00108 typedef struct stat ns_stat_t;
00109 #endif
00110
00111 #ifdef NS_ENABLE_DEBUG
00112 #define DBG(x) do { printf("%-20s ", __func__); printf x; putchar('\n'); \
00113 fflush(stdout); } while(0)
00114 #else
00115 #define DBG(x)
00116 #endif
00117
00118 #ifndef ARRAY_SIZE
00119 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
00120 #endif
00121
00122 #ifdef NS_ENABLE_SSL
00123 #ifdef __APPLE__
00124 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00125 #endif
00126 #include <openssl/ssl.h>
00127 #else
00128 typedef void *SSL;
00129 typedef void *SSL_CTX;
00130 #endif
00131
00132 #ifdef __cplusplus
00133 extern "C" {
00134 #endif // __cplusplus
00135
00136 union socket_address {
00137 struct sockaddr sa;
00138 struct sockaddr_in sin;
00139 #ifdef NS_ENABLE_IPV6
00140 struct sockaddr_in6 sin6;
00141 #else
00142 struct sockaddr sin6;
00143 #endif
00144 };
00145
00146
00147 struct ns_str {
00148 const char *p;
00149 size_t len;
00150 };
00151
00152
00153 struct iobuf {
00154 char *buf;
00155 size_t len;
00156 size_t size;
00157 };
00158
00159 void iobuf_init(struct iobuf *, size_t initial_size);
00160 void iobuf_free(struct iobuf *);
00161 size_t iobuf_append(struct iobuf *, const void *data, size_t data_size);
00162 void iobuf_remove(struct iobuf *, size_t data_size);
00163 void iobuf_resize(struct iobuf *, size_t new_size);
00164
00165
00166
00167 struct ns_connection;
00168 typedef void (*ns_callback_t)(struct ns_connection *, int event_num, void *evp);
00169
00170
00171 #define NS_POLL 0 // Sent to each connection on each call to ns_mgr_poll()
00172 #define NS_ACCEPT 1 // New connection accept()-ed. union socket_address *addr
00173 #define NS_CONNECT 2 // connect() succeeded or failed. int *success_status
00174 #define NS_RECV 3 // Data has benn received. int *num_bytes
00175 #define NS_SEND 4 // Data has been written to a socket. int *num_bytes
00176 #define NS_CLOSE 5 // Connection is closed. NULL
00177
00178
00179 struct ns_mgr {
00180 struct ns_connection *active_connections;
00181 const char *hexdump_file;
00182 sock_t ctl[2];
00183 void *user_data;
00184 };
00185
00186
00187 struct ns_connection {
00188 struct ns_connection *next, *prev;
00189 struct ns_connection *listener;
00190 struct ns_mgr *mgr;
00191
00192 sock_t sock;
00193 union socket_address sa;
00194 struct iobuf recv_iobuf;
00195 struct iobuf send_iobuf;
00196 SSL *ssl;
00197 SSL_CTX *ssl_ctx;
00198 void *user_data;
00199 void *proto_data;
00200 time_t last_io_time;
00201 ns_callback_t callback;
00202
00203 unsigned int flags;
00204 #define NSF_FINISHED_SENDING_DATA (1 << 0)
00205 #define NSF_BUFFER_BUT_DONT_SEND (1 << 1)
00206 #define NSF_SSL_HANDSHAKE_DONE (1 << 2)
00207 #define NSF_CONNECTING (1 << 3)
00208 #define NSF_CLOSE_IMMEDIATELY (1 << 4)
00209 #define NSF_WANT_READ (1 << 5)
00210 #define NSF_WANT_WRITE (1 << 6)
00211 #define NSF_LISTENING (1 << 7)
00212 #define NSF_UDP (1 << 8)
00213
00214 #define NSF_USER_1 (1 << 20)
00215 #define NSF_USER_2 (1 << 21)
00216 #define NSF_USER_3 (1 << 22)
00217 #define NSF_USER_4 (1 << 23)
00218 #define NSF_USER_5 (1 << 24)
00219 #define NSF_USER_6 (1 << 25)
00220 };
00221
00222 void ns_mgr_init(struct ns_mgr *, void *user_data);
00223 void ns_mgr_free(struct ns_mgr *);
00224 time_t ns_mgr_poll(struct ns_mgr *, int milli);
00225 void ns_broadcast(struct ns_mgr *, ns_callback_t, void *, size_t);
00226
00227 struct ns_connection *ns_next(struct ns_mgr *, struct ns_connection *);
00228 struct ns_connection *ns_add_sock(struct ns_mgr *, sock_t,
00229 ns_callback_t, void *);
00230 struct ns_connection *ns_bind(struct ns_mgr *, const char *,
00231 ns_callback_t, void *);
00232 struct ns_connection *ns_connect(struct ns_mgr *, const char *,
00233 ns_callback_t, void *);
00234
00235 int ns_send(struct ns_connection *, const void *buf, int len);
00236 int ns_printf(struct ns_connection *, const char *fmt, ...);
00237 int ns_vprintf(struct ns_connection *, const char *fmt, va_list ap);
00238
00239
00240 void *ns_start_thread(void *(*f)(void *), void *p);
00241 int ns_socketpair(sock_t [2]);
00242 int ns_socketpair2(sock_t [2], int sock_type);
00243 void ns_set_close_on_exec(sock_t);
00244 void ns_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
00245 int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
00246 int ns_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
00247 int ns_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);
00248
00249 #ifdef __cplusplus
00250 }
00251 #endif // __cplusplus
00252
00253 #endif // NS_SKELETON_HEADER_INCLUDED