1 /*
2  * linc-private.h: This file is part of the linc library.
3  *
4  * Authors:
5  *    Elliot Lee     (sopwith@redhat.com)
6  *    Michael Meeks  (michael@ximian.com)
7  *    Mark McLouglin (mark@skynet.ie) & others
8  *
9  * Copyright 2001, Red Hat, Inc., Ximian, Inc.,
10  *                 Sun Microsystems, Inc.
11  */
12 #ifndef _LINK_PRIVATE_H_
13 #define _LINK_PRIVATE_H_
14 
15 #include "config.h"
16 #include <linc/linc.h>
17 
18 #include "linc-debug.h"
19 
20 #ifdef LINK_SSL_SUPPORT
21 
22 #include <openssl/ssl.h>
23 #include <openssl/bio.h>
24 extern SSL_METHOD *link_ssl_method;
25 extern SSL_CTX *link_ssl_ctx;
26 
27 #endif /* LINK_SSL_SUPPORT */
28 
29 typedef struct {
30 	enum {
31 		LINK_COMMAND_DISCONNECT,
32 		LINK_COMMAND_SET_CONDITION,
33 		LINK_COMMAND_SET_IO_THREAD,
34 		LINK_COMMAND_CNX_UNREF
35 	} type;
36 } LinkCommand;
37 
38 typedef struct {
39 	LinkCommand     cmd;
40 	gboolean        complete;
41 } LinkSyncCommand;
42 
43 typedef struct {
44 	LinkCommand     cmd;
45 	LinkConnection *cnx;
46 	GIOCondition    condition;
47 } LinkCommandSetCondition;
48 
49 typedef struct {
50 	LinkCommand     cmd;
51 	LinkConnection *cnx;
52 } LinkCommandDisconnect;
53 
54 typedef struct {
55 	LinkSyncCommand     cmd;
56 	LinkConnection *cnx;
57 } LinkCommandCnxUnref;
58 
59 void link_exec_command (LinkCommand *cmd);
60 void link_connection_exec_disconnect (LinkCommandDisconnect *cmd, gboolean immediate);
61 void link_connection_exec_set_condition (LinkCommandSetCondition *cmd, gboolean immediate);
62 void link_connection_exec_cnx_unref (LinkCommandCnxUnref *cmd, gboolean immediate);
63 
64 /*
65  * Really raw internals, exported for the tests
66  */
67 
68 struct _LinkServerPrivate {
69 	int        fd;
70 	LinkWatch *tag;
71 	GSList    *connections;
72 };
73 
74 struct _LinkWriteOpts {
75 	gboolean block_on_write;
76 };
77 
78 struct _LinkConnectionPrivate {
79 #ifdef LINK_SSL_SUPPORT
80 	SSL         *ssl;
81 #endif
82 	LinkWatch   *tag;
83 	int          fd;
84 
85 	gulong       max_buffer_bytes;
86 	gulong       write_queue_bytes;
87 	GList       *write_queue;
88 	/*
89 	 * This flag is used after a LincConnection is disconnected when
90 	 * an attempt to made to retry the connection. If the attempt returns
91 	 * EINPROGRESS and subsequently is reported as disconnected we want
92 	 * to avoid emitting another "broken" signal.
93 	 */
94 	gboolean     was_disconnected;
95 #ifdef CONNECTION_DEBUG
96 	guint64      total_read_bytes;
97 	guint64      total_written_bytes;
98 #endif
99 };
100 
101 typedef struct {
102 	GSource       source;
103 
104         GIOChannel   *channel;
105 	GPollFD       pollfd;
106 #ifdef G_OS_WIN32
107 	LinkWatch    *link_watch;
108 	SOCKET	      socket;
109 	int	      event_mask;
110 	gboolean      write_would_have_blocked;
111 #endif
112 	GIOCondition  condition;
113 	GIOFunc       callback;
114 	gpointer      user_data;
115 } LinkUnixWatch;
116 
117 struct _LinkWatch {
118 	GSource *main_source;
119 	GSource *link_source;
120 #ifdef G_OS_WIN32
121 	LinkUnixWatch *last_polled_source;
122 #endif
123 };
124 
125 #define LINK_ERR_CONDS (G_IO_ERR|G_IO_HUP|G_IO_NVAL)
126 #define LINK_IN_CONDS  (G_IO_PRI|G_IO_IN)
127 
128 #ifdef G_OS_WIN32
129 
130 /* The functions in the Microsoft C library that correspond to
131  * system calls in Unix don't have any EINTR failure mode.
132  */
133 #define LINK_TEMP_FAILURE_RETRY_SYSCALL(expression, val) \
134     { val = (int) (expression); }
135 
136 #else
137 
138 /* taken from  glibc  */
139 #define LINK_TEMP_FAILURE_RETRY_SYSCALL(expression, val) \
140     { long int __result;                                 \
141        do __result = (long int) (expression);            \
142        while (__result == -1L && errno == EINTR);        \
143        val = __result; }
144 
145 #endif
146 
147 #ifdef HAVE_WINSOCK2_H
148 
149 /* In WinSock2 WSAEINTR can't happen according to the docs, but
150  * it doesn't hurt to check anyway, does it?
151  */
152 #define LINK_TEMP_FAILURE_RETRY_SOCKET(expression, val)                   \
153     { int __result;                                                       \
154        do __result = (int) (expression);                                  \
155        while (__result == SOCKET_ERROR && WSAGetLastError() == WSAEINTR); \
156        val = __result; }
157 
158 #define LINK_CLOSE_SOCKET(fd)  while (closesocket (fd) == SOCKET_ERROR && WSAGetLastError() == WSAEINTR)
159 
160 #else
161 
162 /* On Unix socket API calls are no different from normal system calls */
163 
164 #define LINK_TEMP_FAILURE_RETRY_SOCKET(expression, val) \
165     LINK_TEMP_FAILURE_RETRY_SYSCALL(expression, val)
166 
167 #define LINK_CLOSE_SOCKET(fd)  while (close (fd) < 0 && errno == EINTR)
168 
169 #endif
170 
171 struct sockaddr *link_protocol_get_sockaddr (const LinkProtocolInfo *proto,
172 					     const char             *hostname,
173 					     const char             *service,
174 					     LinkSockLen            *saddr_len);
175 
176 gboolean         link_protocol_get_sockinfo (const LinkProtocolInfo *proto,
177 					     const struct sockaddr  *saddr,
178 					     gchar                 **hostname,
179 					     gchar                 **service);
180 
181 gboolean         link_protocol_is_local     (const LinkProtocolInfo  *proto,
182 					     const struct sockaddr   *saddr,
183 					     LinkSockLen              saddr_len);
184 
185 void             link_protocol_destroy_cnx  (const LinkProtocolInfo  *proto,
186 					     int                      fd,
187 					     const char              *host,
188 					     const char              *service);
189 
190 void             link_protocol_destroy_addr (const LinkProtocolInfo  *proto,
191 					     int                      fd,
192 					     struct sockaddr         *saddr);
193 
194 LinkWatch       *link_io_add_watch_fd       (int                     fd,
195 					     GIOCondition            condition,
196 					     GIOFunc                 func,
197 					     gpointer                user_data);
198 
199 void             link_io_remove_watch       (LinkWatch              *w);
200 void             link_watch_set_condition   (LinkWatch              *w,
201 					     GIOCondition            condition);
202 void             link_watch_move_io         (LinkWatch              *w,
203 					     gboolean                to_io_thread);
204 
205 GMainContext    *link_main_get_context      (void);
206 GMainContext    *link_thread_io_context     (void);
207 gboolean         link_in_io_thread          (void);
208 gboolean         link_mutex_is_locked       (GMutex *lock);
209 void             link_lock                  (void);
210 void             link_unlock                (void);
211 gboolean         link_is_locked             (void);
212 void             link_servers_move_io_T     (gboolean to_io_thread);
213 void             link_connections_move_io_T (gboolean to_io_thread);
214 
215 #ifdef G_OS_WIN32
216 void		 link_win32_watch_set_write_wouldblock (LinkWatch    *watch,
217 							gboolean      flag);
218 #endif
219 
220 #endif /* _LINK_PRIVATE_H */
221