1 #ifndef __GSK_SOCKET_ADDRESS_H_
2 #define __GSK_SOCKET_ADDRESS_H_
3 
4 #include <glib-object.h>
5 #include "gskipv4.h"
6 
7 G_BEGIN_DECLS
8 
9 /* --- typedefs --- */
10 typedef struct _GskSocketAddress GskSocketAddress;
11 typedef struct _GskSocketAddressClass GskSocketAddressClass;
12 typedef struct _GskSocketAddressIpv4 GskSocketAddressIpv4;
13 typedef struct _GskSocketAddressIpv4Class GskSocketAddressIpv4Class;
14 typedef struct _GskSocketAddressIpv6 GskSocketAddressIpv6;
15 typedef struct _GskSocketAddressIpv6Class GskSocketAddressIpv6Class;
16 typedef struct _GskSocketAddressLocal GskSocketAddressLocal;
17 typedef struct _GskSocketAddressLocalClass GskSocketAddressLocalClass;
18 typedef struct _GskSocketAddressEthernet GskSocketAddressEthernet;
19 typedef struct _GskSocketAddressEthernetClass GskSocketAddressEthernetClass;
20 
21 /* --- type macros --- */
22 #define GSK_TYPE_SOCKET_ADDRESS			  (gsk_socket_address_get_type ())
23 #define GSK_SOCKET_ADDRESS(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_SOCKET_ADDRESS, GskSocketAddress))
24 #define GSK_SOCKET_ADDRESS_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_SOCKET_ADDRESS, GskSocketAddressClass))
25 #define GSK_SOCKET_ADDRESS_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_SOCKET_ADDRESS, GskSocketAddressClass))
26 #define GSK_IS_SOCKET_ADDRESS(obj)                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_SOCKET_ADDRESS))
27 #define GSK_IS_SOCKET_ADDRESS_CLASS(klass)        (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_SOCKET_ADDRESS))
28 #define GSK_TYPE_SOCKET_ADDRESS_IPV4              (gsk_socket_address_ipv4_get_type ())
29 #define GSK_SOCKET_ADDRESS_IPV4(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_SOCKET_ADDRESS_IPV4, GskSocketAddressIpv4))
30 #define GSK_SOCKET_ADDRESS_IPV4_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_SOCKET_ADDRESS_IPV4, GskSocketAddressIpv4Class))
31 #define GSK_SOCKET_ADDRESS_IPV4_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_SOCKET_ADDRESS_IPV4, GskSocketAddressIpv4Class))
32 #define GSK_IS_SOCKET_ADDRESS_IPV4(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_SOCKET_ADDRESS_IPV4))
33 #define GSK_IS_SOCKET_ADDRESS_IPV4_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_SOCKET_ADDRESS_IPV4))
34 #define GSK_TYPE_SOCKET_ADDRESS_IPV6              (gsk_socket_address_ipv6_get_type ())
35 #define GSK_SOCKET_ADDRESS_IPV6(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_SOCKET_ADDRESS_IPV6, GskSocketAddressIpv6))
36 #define GSK_SOCKET_ADDRESS_IPV6_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_SOCKET_ADDRESS_IPV6, GskSocketAddressIpv6Class))
37 #define GSK_SOCKET_ADDRESS_IPV6_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_SOCKET_ADDRESS_IPV6, GskSocketAddressIpv6Class))
38 #define GSK_IS_SOCKET_ADDRESS_IPV6(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_SOCKET_ADDRESS_IPV6))
39 #define GSK_IS_SOCKET_ADDRESS_IPV6_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_SOCKET_ADDRESS_IPV6))
40 #define GSK_TYPE_SOCKET_ADDRESS_LOCAL		  (gsk_socket_address_local_get_type ())
41 #define GSK_SOCKET_ADDRESS_LOCAL(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_SOCKET_ADDRESS_LOCAL, GskSocketAddressLocal))
42 #define GSK_SOCKET_ADDRESS_LOCAL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_SOCKET_ADDRESS_LOCAL, GskSocketAddressLocalClass))
43 #define GSK_SOCKET_ADDRESS_LOCAL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_SOCKET_ADDRESS_LOCAL, GskSocketAddressLocalClass))
44 #define GSK_IS_SOCKET_ADDRESS_LOCAL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_SOCKET_ADDRESS_LOCAL))
45 #define GSK_IS_SOCKET_ADDRESS_LOCAL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_SOCKET_ADDRESS_LOCAL))
46 #define GSK_TYPE_SOCKET_ADDRESS_ETHERNET			(gsk_socket_address_ethernet_get_type ())
47 #define GSK_SOCKET_ADDRESS_ETHERNET(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_SOCKET_ADDRESS_ETHERNET, GskSocketAddressEthernet))
48 #define GSK_SOCKET_ADDRESS_ETHERNET_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_SOCKET_ADDRESS_ETHERNET, GskSocketAddressEthernetClass))
49 #define GSK_SOCKET_ADDRESS_ETHERNET_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_SOCKET_ADDRESS_ETHERNET, GskSocketAddressEthernetClass))
50 #define GSK_IS_SOCKET_ADDRESS_ETHERNET(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_SOCKET_ADDRESS_ETHERNET))
51 #define GSK_IS_SOCKET_ADDRESS_ETHERNET_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_SOCKET_ADDRESS_ETHERNET))
52 
53 
54 /* Useful quarks (for g_object_get_qdata) */
55 #define GSK_SOCKET_ADDRESS_REMOTE_QUARK	(gsk_socket_address_get_remote_quark())
56 #define GSK_SOCKET_ADDRESS_LOCAL_QUARK	(gsk_socket_address_get_local_quark())
57 
58 /* --- structures --- */
59 struct _GskSocketAddressClass
60 {
61   GObjectClass object_class;
62   gsize sizeof_native_address;
63   gint protocol_family;		/* eg PF_INET, PF_LOCAL etc */
64   gint address_family;		/* eg AF_INET, AF_LOCAL etc */
65   gboolean (*to_native)  (GskSocketAddress *address,
66 			  gpointer          output);
67   gboolean (*from_native)(GskSocketAddress *address,
68 			  gconstpointer     sockaddr_data,
69 			  gsize             sockaddr_length);
70   char    *(*to_string)  (GskSocketAddress *address);
71   /* note: both addresses will be of exactly the same type */
72   gboolean (*equals)     (GskSocketAddress *addr1,
73 			  GskSocketAddress *addr2);
74   guint    (*hash)       (GskSocketAddress *addr);
75 };
76 struct _GskSocketAddress
77 {
78   GObject      object;
79 };
80 
81 struct _GskSocketAddressIpv4Class
82 {
83   GskSocketAddressClass socket_address_class;
84 };
85 struct _GskSocketAddressIpv4
86 {
87   GskSocketAddress      socket_address;
88   guint8 ip_address[4];
89   guint16 ip_port;
90 };
91 
92 /* aka 'unix-domain addresses' */
93 struct _GskSocketAddressLocalClass
94 {
95   GskSocketAddressClass socket_address_class;
96   guint max_path_length;
97 };
98 struct _GskSocketAddressLocal
99 {
100   GskSocketAddress      socket_address;
101   char *path;
102 };
103 
104 /* ipv6 socket addresses, where available */
105 struct _GskSocketAddressIpv6Class
106 {
107   GskSocketAddressClass socket_address_class;
108 };
109 struct _GskSocketAddressIpv6
110 {
111   GskSocketAddress      socket_address;
112   guint16 port;
113   guint8 address[16];
114 
115   guint32 flow_info;	/* TODO figure this out */
116   guint scope_id;	/* TODO figure this out */
117 };
118 
119 struct _GskSocketAddressEthernetClass
120 {
121   GskSocketAddressClass socket_address_class;
122 };
123 struct _GskSocketAddressEthernet
124 {
125   GskSocketAddress      socket_address;
126   guint8                mac_address[6];
127 };
128 
129 
130 /* --- prototypes --- */
131 GskSocketAddress *gsk_socket_address_from_native   (gconstpointer native_data,
132 						    gsize    native_size);
133 gint              gsk_socket_address_protocol_family(GskSocketAddress *address);
134 gint              gsk_socket_address_address_family(GskSocketAddress *address);
135 guint             gsk_socket_address_sizeof_native (GskSocketAddress *address);
136 gboolean          gsk_socket_address_to_native     (GskSocketAddress *address,
137 						    gpointer          output,
138 						    GError          **error);
139 char             *gsk_socket_address_to_string     (GskSocketAddress *address);
140 
141 
142 /* ipv4 specific */
143 
144 #define gsk_socket_address_ipv4_localhost(port) \
145 	gsk_socket_address_ipv4_new (gsk_ipv4_ip_address_loopback, (port))
146 
147 /* (ip_addr is 4-bytes long) */
148 GskSocketAddress *gsk_socket_address_ipv4_new      (const guint8     *ip_address,
149 						    guint16           port);
150 
151 /* ipv6 specific */
152 gboolean gsk_socket_address_system_supports_ipv6 (void) G_GNUC_CONST;
153 
154 /* (addr is 16-bytes long) */
155 GskSocketAddress *gsk_socket_address_ipv6_new      (const guint8     *address,
156 						    guint16           port);
157 
158 /* local (unix) specific */
159 GskSocketAddress *gsk_socket_address_local_new     (const char       *path);
160 
161 /* ethernet specific */
162 GskSocketAddress *gsk_socket_address_ethernet_new  (const guint8     *mac_addr);
163 
164 #ifndef GSK_DISABLE_DEPRECATED
165 #define gsk_socket_address_new_ethernet gsk_socket_address_ethernet_new
166 #define gsk_socket_address_new_local    gsk_socket_address_local_new
167 #endif
168 
169 /* --- implementing new sock-addr types --- */
170 /* call from the relevant class's class_init */
171 void  gsk_socket_address_register_subclass (GskSocketAddressClass *klass);
172 
173 
174 /* --- connecting to a socket-address --- */
175 /* gsk_socket_address_connect_fd() returns a file descriptor.
176  * if it returns >= 0:
177  *   if *is_connected, the fd is ready to go.
178  *   if !*is_connected, you should watch for GSK_SOCKET_ADDRESS_CONNECT_EVENTS.
179  *   when an event occurs call gsk_socket_address_finish_fd().  if it returns
180  *   TRUE the fd is ready.  if it returns FALSE:
181  *      if *error != NULL, then an error occurred.
182  *      if *error == NULL, then repeat waiting for an event.
183  * if it returns -1, then an error occurred immediately.
184  */
185 int               gsk_socket_address_connect_fd    (GskSocketAddress *address,
186 						    gboolean         *is_connected,
187 						    GError          **error);
188 
189 /* NOTE: this function could also be called gsk_fd_finish_connecting();
190    it has nothing to do with GskSocketAddress.
191    it just pairs with gsk_socket_address_connect_fd(). */
192 gboolean          gsk_socket_address_finish_fd     (int               fd,
193 						    GError          **error);
194 
195 /* --- for making a hash-table of addresses --- */
196 gboolean          gsk_socket_address_equals        (gconstpointer     address_a_ptr,
197 						    gconstpointer     address_b_ptr);
198 guint             gsk_socket_address_hash          (gconstpointer     address_ptr);
199 
200 
201 /*< private >*/
202 GQuark gsk_socket_address_get_remote_quark ();
203 GQuark gsk_socket_address_get_local_quark ();
204 GType gsk_socket_address_get_type(void) G_GNUC_CONST;
205 GType gsk_socket_address_ipv4_get_type(void) G_GNUC_CONST;
206 GType gsk_socket_address_ipv6_get_type(void) G_GNUC_CONST;
207 GType gsk_socket_address_local_get_type(void) G_GNUC_CONST;
208 GType gsk_socket_address_ethernet_get_type(void) G_GNUC_CONST;
209 
210 
211 G_END_DECLS
212 
213 #endif
214