Some winsock improvements
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Your operating system
|
# Your operating environment
|
||||||
#
|
#
|
||||||
|
|
||||||
OS = CYGWIN
|
OS = CYGWIN
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#define NO_GETHOSTBYNAME2
|
#define NO_GETHOSTBYNAME2
|
||||||
#define NO_INET_ATON /* implies NO_INET_PTON */
|
#define NO_INET_ATON /* implies NO_INET_PTON */
|
||||||
#define NO_INET_NTOP
|
#define NO_INET_NTOP
|
||||||
|
#define NO_SSIZE_T
|
||||||
#define NO_STRL
|
#define NO_STRL
|
||||||
#define NO_Z_FORMAT
|
#define NO_Z_FORMAT
|
||||||
#define WINSOCK
|
#define WINSOCK
|
||||||
@ -103,6 +104,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@ -112,10 +114,12 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
typedef SOCKET socket_t;
|
typedef SOCKET socket_t;
|
||||||
typedef signed long ssize_t;
|
|
||||||
#else
|
#else
|
||||||
typedef int socket_t;
|
typedef int socket_t;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NO_SSIZE_T
|
||||||
|
typedef signed long ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prints out the file name, line number, and function name before log message
|
* Prints out the file name, line number, and function name before log message
|
||||||
|
@ -86,7 +86,7 @@ extern samerr_t sam_connect(const char *samhost, uint16_t samport,
|
|||||||
const char *destname, sam_conn_t style, uint_t tunneldepth);
|
const char *destname, sam_conn_t style, uint_t tunneldepth);
|
||||||
extern void sam_naming_lookup(const char *name);
|
extern void sam_naming_lookup(const char *name);
|
||||||
extern bool sam_read_buffer(void);
|
extern bool sam_read_buffer(void);
|
||||||
extern char *sam_strerror(samerr_t code);
|
extern const char *sam_strerror(samerr_t code);
|
||||||
/* SAM controls - callbacks */
|
/* SAM controls - callbacks */
|
||||||
extern void (*sam_diedback)(void);
|
extern void (*sam_diedback)(void);
|
||||||
extern void (*sam_logback)(char *str);
|
extern void (*sam_logback)(char *str);
|
||||||
|
@ -41,6 +41,11 @@ static samerr_t sam_session_create(const char *destname, sam_conn_t style,
|
|||||||
uint_t tunneldepth);
|
uint_t tunneldepth);
|
||||||
static bool sam_socket_connect(const char *host, uint16_t port);
|
static bool sam_socket_connect(const char *host, uint16_t port);
|
||||||
static bool sam_socket_resolve(const char *hostname, char *ipaddr);
|
static bool sam_socket_resolve(const char *hostname, char *ipaddr);
|
||||||
|
#ifdef WINSOCK
|
||||||
|
static samerr_t sam_winsock_cleanup(void);
|
||||||
|
static samerr_t sam_winsock_startup(void);
|
||||||
|
static const char *sam_winsock_strerror(int code);
|
||||||
|
#endif
|
||||||
static ssize_t sam_write(const void *buf, size_t n);
|
static ssize_t sam_write(const void *buf, size_t n);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,6 +88,8 @@ bool sam_close(void)
|
|||||||
if (closesocket(samd) == 0) {
|
if (closesocket(samd) == 0) {
|
||||||
samd_connected = false;
|
samd_connected = false;
|
||||||
return true;
|
return true;
|
||||||
|
if (sam_winsock_cleanup() != SAM_OK)
|
||||||
|
return false;
|
||||||
#else
|
#else
|
||||||
if (close(samd) == 0) {
|
if (close(samd) == 0) {
|
||||||
samd_connected = false;
|
samd_connected = false;
|
||||||
@ -132,23 +139,9 @@ samerr_t sam_connect(const char *samhost, uint16_t samport,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
/*
|
rc = sam_winsock_startup();
|
||||||
* Is Windows retarded or what?
|
if (rc != SAM_OK)
|
||||||
*/
|
return rc;
|
||||||
WORD wVersionRequested;
|
|
||||||
WSADATA wsaData;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
wVersionRequested = MAKEWORD(1, 1);
|
|
||||||
err = WSAStartup(wVersionRequested, &wsaData);
|
|
||||||
if (err != 0) {
|
|
||||||
SAMLOGS("WSAStartup() failed");
|
|
||||||
return SAM_SOCKET_ERROR;
|
|
||||||
}
|
|
||||||
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1 ) {
|
|
||||||
SAMLOGS("Bad WinSock version");
|
|
||||||
return SAM_SOCKET_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!sam_socket_connect(samhost, samport)) {
|
if (!sam_socket_connect(samhost, samport)) {
|
||||||
@ -953,7 +946,7 @@ samerr_t sam_stream_send(sam_sid_t stream_id, const void *data, size_t size)
|
|||||||
*
|
*
|
||||||
* Returns: error string
|
* Returns: error string
|
||||||
*/
|
*/
|
||||||
char *sam_strerror(samerr_t code)
|
const char *sam_strerror(samerr_t code)
|
||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case SAM_OK: /* Operation completed succesfully */
|
case SAM_OK: /* Operation completed succesfully */
|
||||||
@ -994,6 +987,177 @@ char *sam_strerror(samerr_t code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WINSOCK
|
||||||
|
/*
|
||||||
|
* Unloads the Winsock network subsystem
|
||||||
|
*
|
||||||
|
* Returns: SAM error code
|
||||||
|
*/
|
||||||
|
samerr_t sam_winsock_cleanup(void)
|
||||||
|
{
|
||||||
|
if (WSACleanup() == SOCKET_ERROR) {
|
||||||
|
SAMLOG("WSACleanup() failed (%s)",
|
||||||
|
sam_winsock_strerror(WSAGetLastError()));
|
||||||
|
return SAM_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SAM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loads the Winsock network sucksystem
|
||||||
|
*
|
||||||
|
* Returns: SAM error code
|
||||||
|
*/
|
||||||
|
samerr_t sam_winsock_startup(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Is Windows retarded or what?
|
||||||
|
*/
|
||||||
|
WORD wVersionRequested;
|
||||||
|
WSADATA wsaData;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
rc = WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAMLOG("WSAStartup() failed (%s)", sam_winsock_strerror(rc));
|
||||||
|
return SAM_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
|
||||||
|
SAMLOGS("Bad Winsock version");
|
||||||
|
sam_winsock_cleanup();
|
||||||
|
return SAM_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SAM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apparently Winsock does not have a strerror() equivalent for its functions
|
||||||
|
*
|
||||||
|
* code - code from WSAGetLastError()
|
||||||
|
*
|
||||||
|
* Returns: error string (from http://msdn.microsoft.com/library/default.asp?
|
||||||
|
* url=/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp)
|
||||||
|
*/
|
||||||
|
const char *sam_winsock_strerror(int code)
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case WSAEINTR:
|
||||||
|
return "Interrupted function call";
|
||||||
|
case WSAEACCES: // yes, that is the correct spelling
|
||||||
|
return "Permission denied";
|
||||||
|
case WSAEFAULT:
|
||||||
|
return "Bad address";
|
||||||
|
case WSAEINVAL:
|
||||||
|
return "Invalid argument";
|
||||||
|
case WSAEMFILE:
|
||||||
|
return "Too many open files";
|
||||||
|
case WSAEWOULDBLOCK:
|
||||||
|
return "Resource temporarily unavailable";
|
||||||
|
case WSAEINPROGRESS:
|
||||||
|
return "Operation now in progress";
|
||||||
|
case WSAEALREADY:
|
||||||
|
return "Operation already in progress";
|
||||||
|
case WSAENOTSOCK:
|
||||||
|
return "Socket operations on nonsocket";
|
||||||
|
case WSAEDESTADDRREQ:
|
||||||
|
return "Destination address required";
|
||||||
|
case WSAEMSGSIZE:
|
||||||
|
return "Message too long";
|
||||||
|
case WSAEPROTOTYPE:
|
||||||
|
return "Protocol wrong type for socket";
|
||||||
|
case WSAENOPROTOOPT:
|
||||||
|
return "Bad protocol option";
|
||||||
|
case WSAEPROTONOSUPPORT:
|
||||||
|
return "Protocol not supported";
|
||||||
|
case WSAESOCKTNOSUPPORT:
|
||||||
|
return "Socket type not supported";
|
||||||
|
case WSAEOPNOTSUPP:
|
||||||
|
return "Operation not supported";
|
||||||
|
case WSAEPFNOSUPPORT:
|
||||||
|
return "Protocol family not supported";
|
||||||
|
case WSAEAFNOSUPPORT:
|
||||||
|
return "Address family not supported by protocol family";
|
||||||
|
case WSAEADDRINUSE:
|
||||||
|
return "Address already in use";
|
||||||
|
case WSAEADDRNOTAVAIL:
|
||||||
|
return "Cannot assign requested address";
|
||||||
|
case WSAENETDOWN:
|
||||||
|
return "Network is down";
|
||||||
|
case WSAENETUNREACH:
|
||||||
|
return "Network is unreachable";
|
||||||
|
case WSAENETRESET:
|
||||||
|
return "Network dropped connection on reset";
|
||||||
|
case WSAECONNABORTED:
|
||||||
|
return "Software caused connection abort";
|
||||||
|
case WSAECONNRESET:
|
||||||
|
return "Connection reset by peer";
|
||||||
|
case WSAENOBUFS:
|
||||||
|
return "No buffer space available";
|
||||||
|
case WSAEISCONN:
|
||||||
|
return "Socket is already connected";
|
||||||
|
case WSAENOTCONN:
|
||||||
|
return "Socket is not connected";
|
||||||
|
case WSAESHUTDOWN:
|
||||||
|
return "Cannot send after socket shutdown";
|
||||||
|
case WSAETIMEDOUT:
|
||||||
|
return "Connection timed out";
|
||||||
|
case WSAECONNREFUSED:
|
||||||
|
return "Connection refused";
|
||||||
|
case WSAEHOSTDOWN:
|
||||||
|
return "Host is down";
|
||||||
|
case WSAEHOSTUNREACH:
|
||||||
|
return "No route to host";
|
||||||
|
case WSAEPROCLIM:
|
||||||
|
return "Too many processes";
|
||||||
|
case WSASYSNOTREADY:
|
||||||
|
return "Network subsystem is unavailable";
|
||||||
|
case WSAVERNOTSUPPORTED:
|
||||||
|
return "Winsock.dll version out of range";
|
||||||
|
case WSANOTINITIALISED:
|
||||||
|
return "Successful WSAStartup not yet performed";
|
||||||
|
case WSAEDISCON:
|
||||||
|
return "Graceful shutdown in progress";
|
||||||
|
case WSATYPE_NOT_FOUND:
|
||||||
|
return "Class type not found";
|
||||||
|
case WSAHOST_NOT_FOUND:
|
||||||
|
return "Host not found";
|
||||||
|
case WSATRY_AGAIN:
|
||||||
|
return "Nonauthoritative host not found";
|
||||||
|
case WSANO_RECOVERY:
|
||||||
|
return "This is a nonrecoverable error";
|
||||||
|
case WSANO_DATA:
|
||||||
|
return "Valid name, no data record of requested type";
|
||||||
|
/* None of this shit compiles under Mingw - who knows why...
|
||||||
|
case WSA_INVALID_HANDLE:
|
||||||
|
return "Specified event object handle is invalid";
|
||||||
|
case WSA_INVALID_PARAMETER:
|
||||||
|
return "One or more parameters are invalid";
|
||||||
|
case WSA_IO_INCOMPLETE:
|
||||||
|
return "Overlapped I/O event object not in signaled state";
|
||||||
|
case WSA_IO_PENDING:
|
||||||
|
return "Overlapped operations will complete later";
|
||||||
|
case WSA_NOT_ENOUGH_MEMORY:
|
||||||
|
return "Insufficient memory available";
|
||||||
|
case WSA_OPERATION_ABORTED:
|
||||||
|
return "Overlapped operation aborted";
|
||||||
|
case WSAINVALIDPROCTABLE:
|
||||||
|
return "Invalid procedure table from service provider";
|
||||||
|
case WSAINVALIDPROVIDER:
|
||||||
|
return "Invalid service provider version number";
|
||||||
|
case WSAPROVIDERFAILEDINIT:
|
||||||
|
return "Unable to initialize a service provider";
|
||||||
|
*/
|
||||||
|
case WSASYSCALLFAILURE:
|
||||||
|
return "System call failure";
|
||||||
|
default:
|
||||||
|
return "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sends `n' bytes to the SAM host
|
* Sends `n' bytes to the SAM host
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user