aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common/Sockets.h
blob: c821748802b84e9264d0574b522815c83e19012d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*****************************************************************************/
/* Sockets.h                              Copyright (c) Ladislav Zezula 2021 */
/*---------------------------------------------------------------------------*/
/* MIME parsing functions for CascLib                                        */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 13.02.21  1.00  Lad  Created                                              */
/*****************************************************************************/

#ifndef __SOCKET_H__
#define __SOCKET_H__

//-----------------------------------------------------------------------------
// Defines

#ifndef INVALID_SOCKET
#define INVALID_SOCKET (SOCKET)(-1)
#endif

#ifndef SOCKET_ERROR
#define SOCKET_ERROR   (-1)
#endif

#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif

#ifndef WSAECONNRESET
#define WSAECONNRESET       10054L
#endif

#ifndef EPIPE
#define EPIPE               32
#endif

#define CASC_PORT_HTTP      80
#define CASC_PORT_RIBBIT    1119

//-----------------------------------------------------------------------------
// The CASC_SOCKET class

typedef class CASC_SOCKET_CACHE * PCASC_SOCKET_CACHE;
typedef class CASC_SOCKET * PCASC_SOCKET;
typedef struct addrinfo * PADDRINFO;

class CASC_SOCKET
{
    public:

    char * ReadResponse(const char * request, size_t request_length, CASC_MIME_RESPONSE & MimeResponse);
    DWORD AddRef();
    void Release();

    private:

    // Constructor and destructor
    static int GetSockError();
    static DWORD GetAddrInfoWrapper(const char * hostName, unsigned portNum, PADDRINFO hints, PADDRINFO * ppResult);
    static SOCKET CreateAndConnect(addrinfo * remoteItem);
    static SOCKET ReconnectAfterShutdown(SOCKET & sock, addrinfo * remoteItem);
    static PCASC_SOCKET New(addrinfo * remoteList, addrinfo * remoteItem, const char * hostName, unsigned portNum, SOCKET sock);
    static PCASC_SOCKET Connect(const char * hostName, unsigned portNum);

    // Frees all resources and deletes the socket
    void Delete();

    // Entities allowed to manipulate with the class
    friend CASC_SOCKET * sockets_connect(const char * hostName, unsigned portNum);
    friend char * sockets_read_response(PCASC_SOCKET pSocket, const char * request, size_t request_length, size_t * PtrLength);
    friend class CASC_SOCKET_CACHE;

    PCASC_SOCKET_CACHE pCache;          // Pointer to the cache. If NULL, the socket is not cached
    PCASC_SOCKET pPrev;                 // Pointer to the prev socket in the list
    PCASC_SOCKET pNext;                 // Pointer to the next socket in the list
    PADDRINFO remoteList;               // List of the remote host informations
    PADDRINFO remoteItem;               // The particular host picked during the last connection attempt
    CASC_LOCK Lock;                     // Lock for single threaded access
    SOCKET sock;                        // Opened and connected socket
    DWORD dwRefCount;                   // Number of references
    DWORD portNum;                      // Port number
    char hostName[1];                   // Buffer for storing remote host (variable length)
};

//-----------------------------------------------------------------------------
// Socket cache class

class CASC_SOCKET_CACHE
{
    public:

    CASC_SOCKET_CACHE();
    ~CASC_SOCKET_CACHE();

    PCASC_SOCKET Find(const char * hostName, unsigned portNum);
    PCASC_SOCKET InsertSocket(PCASC_SOCKET pSocket);
    void UnlinkSocket(PCASC_SOCKET pSocket);

    void SetCaching(bool bAddRef);
    void PurgeAll();

    private:

    PCASC_SOCKET pFirst;
    PCASC_SOCKET pLast;
    DWORD dwRefCount;
};

//-----------------------------------------------------------------------------
// Public functions

PCASC_SOCKET sockets_connect(const char * hostName, unsigned portNum);
void sockets_set_caching(bool caching);

#endif  // __SOCKET_H__