~ubuntu-branches/ubuntu/karmic/erlang/karmic

« back to all changes in this revision

Viewing changes to debian/patches/ssl.patch

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2008-11-04 22:26:12 UTC
  • mfrom: (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20081104222612-1uwzavuet6ar35fw
Tags: 1:12.b.3-dfsg-4ubuntu1
* Merge from Debian unstable, remaining Ubuntu changes:
  + debian/patches/glibc2.8_compatibility.patch:
    - Fix FTBFS with new glibc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ssl.patch by Mikael Magnusson <mikma@users.sourceforge.net>
 
2
 
 
3
Patch adds support for IPv6 to the ssl application.
 
4
 
 
5
--- erlang-12.b.3-dfsg.orig/erts/configure.in
 
6
+++ erlang-12.b.3-dfsg/erts/configure.in
 
7
@@ -1349,6 +1349,8 @@
 
8
        fi
 
9
 fi
 
10
 AC_CHECK_FUNCS([getnameinfo getipnodebyname getipnodebyaddr gethostbyname2])
 
11
+AC_CHECK_FUNCS([inet_pton])
 
12
+AC_CHECK_TYPES([struct sockaddr_storage],,,[#include <netinet/in.h>])
 
13
 
 
14
 AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlopen \
 
15
                pread pwrite writev memmove strerror strerror_r strncasecmp \
 
16
--- erlang-12.b.3-dfsg.orig/erts/config.h.in
 
17
+++ erlang-12.b.3-dfsg/erts/config.h.in
 
18
@@ -241,6 +241,9 @@
 
19
 /* Define if ipv6 is present */
 
20
 #undef HAVE_IN6
 
21
 
 
22
+/* Define to 1 if you have the `inet_pton' function. */
 
23
+#undef HAVE_INET_PTON
 
24
+
 
25
 /* Define to 1 if you have the <inttypes.h> header file. */
 
26
 #undef HAVE_INTTYPES_H
 
27
 
 
28
@@ -382,6 +385,9 @@
 
29
 /* Define to 1 if `ssh_data' is member of `struct sctp_send_failed'. */
 
30
 #undef HAVE_STRUCT_SCTP_SEND_FAILED_SSH_DATA
 
31
 
 
32
+/* Define to 1 if the system has the type `struct sockaddr_storage'. */
 
33
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
 
34
+
 
35
 /* Define to 1 if you have the <syslog.h> header file. */
 
36
 #undef HAVE_SYSLOG_H
 
37
 
 
38
--- erlang-12.b.3-dfsg.orig/lib/ssl/c_src/esock.c
 
39
+++ erlang-12.b.3-dfsg/lib/ssl/c_src/esock.c
 
40
@@ -130,6 +130,11 @@
 
41
 #define INADDR_NONE 0xffffffff  /* Should be in <netinet/in.h>.  */
 
42
 #endif
 
43
 
 
44
+#if defined(HAVE_STRUCT_SOCKADDR_STORAGE) && defined(HAVE_GETNAMEINFO) && \
 
45
+    defined(HAVE_INET_PTON)
 
46
+# define USE_IPV6
 
47
+#endif
 
48
+
 
49
 #include "esock.h"
 
50
 #include "debuglog.h"
 
51
 #include "esock_utils.h"
 
52
@@ -176,6 +181,15 @@
 
53
 static void dump_connections(void);
 
54
 static int check_num_sock_fds(FD fd); 
 
55
 static void safe_close(FD fd);
 
56
+
 
57
+#if defined(USE_IPV6)
 
58
+static FD do_connect6(char *lipstring, int lport, char *fipstring, int fport);
 
59
+static FD do_listen6(char *ipstring, int lport, int backlog, int *aport);
 
60
+static int ss_getport(const struct sockaddr *sa, socklen_t size);
 
61
+static int reply_sockaddr(int cmd, int fd, const struct sockaddr *sa,
 
62
+                         socklen_t size);
 
63
+#endif
 
64
+
 
65
 static Connection *new_connection(int state, FD fd);
 
66
 static Connection *get_connection(FD fd);
 
67
 static void remove_connection(Connection *conn);
 
68
@@ -364,7 +378,11 @@
 
69
     char *protocol_vsn, *cipher;
 
70
     unsigned char *cert, *bin;
 
71
     int certlen, binlen;
 
72
+#if defined(USE_IPV6)
 
73
+    struct sockaddr_storage iserv_addr;
 
74
+#else
 
75
     struct sockaddr_in iserv_addr;
 
76
+#endif
 
77
     int sret = 1;
 
78
     Connection *cp, *cpnext, *newcp;
 
79
     Proxy *pp;
 
80
@@ -441,7 +459,12 @@
 
81
                        /* Add to pending proxy connections */
 
82
                        SET_NONBLOCKING(proxysock);
 
83
                        pp = new_proxy(proxysock);
 
84
+#if defined(USE_IPV6)
 
85
+                       pp->peer_port =
 
86
+                           ss_getport((struct sockaddr *)&iserv_addr, length);
 
87
+#else
 
88
                        pp->peer_port = ntohs(iserv_addr.sin_port);
 
89
+#endif
 
90
                        DEBUGF(("-----------------------------------\n"));
 
91
                        DEBUGF(("[PROXY_LISTEN_SOCK] conn accepted: "
 
92
                                "proxyfd = %d, "
 
93
@@ -496,9 +519,14 @@
 
94
                         * reply  = {cmd(1), fd(4), port(2), 
 
95
                         *          ipstring(N), 0(1)}
 
96
                         */
 
97
+#if defined(USE_IPV6)
 
98
+                       reply_sockaddr(ESOCK_GETPEERNAME_REP, fd,
 
99
+                                      (struct sockaddr*)&iserv_addr, length);
 
100
+#else
 
101
                        reply(ESOCK_GETPEERNAME_REP, "42s", fd, 
 
102
                              ntohs(iserv_addr.sin_port), 
 
103
                              inet_ntoa(iserv_addr.sin_addr));
 
104
+#endif
 
105
                    }
 
106
                    break;
 
107
 
 
108
@@ -522,9 +550,14 @@
 
109
                         * reply  = {cmd(1), fd(4), port(2), 
 
110
                         *          ipstring(N), 0(1)}
 
111
                         */
 
112
+#if defined(USE_IPV6)
 
113
+                       reply_sockaddr(ESOCK_GETSOCKNAME_REP, fd,
 
114
+                                      (struct sockaddr*)&iserv_addr, length);
 
115
+#else
 
116
                        reply(ESOCK_GETSOCKNAME_REP, "42s", fd, 
 
117
                              ntohs(iserv_addr.sin_port),
 
118
                              inet_ntoa(iserv_addr.sin_addr));
 
119
+#endif
 
120
                    }
 
121
                    break;
 
122
 
 
123
@@ -699,8 +732,7 @@
 
124
                    }
 
125
                    DEBUGF(("-> PASSIVE_LISTENING (fd = %d)\n", listensock));
 
126
                    /* Publish listensock */
 
127
-                   reply(ESOCK_LISTEN_REP, "442", intref, listensock,
 
128
-                         ntohs(iserv_addr.sin_port));
 
129
+                   reply(ESOCK_LISTEN_REP, "442", intref, listensock, lport);
 
130
                    break;
 
131
 
 
132
                case ESOCK_TRANSPORT_ACCEPT_CMD:
 
133
@@ -1513,6 +1545,11 @@
 
134
     struct sockaddr_in sock_addr;
 
135
     long inaddr;
 
136
     FD fd;
 
137
+
 
138
+#if defined(USE_IPV6)
 
139
+    if (strchr(fipstring, ':'))
 
140
+       return do_connect6(lipstring, lport, fipstring, fport);
 
141
+#endif
 
142
    
 
143
     if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_FD) {
 
144
        DEBUGF(("Error calling socket()\n"));
 
145
@@ -1570,9 +1607,14 @@
 
146
     static int one = 1;                /* Type must be int, not long */
 
147
     struct sockaddr_in sock_addr;
 
148
     long inaddr;
 
149
-    int length;
 
150
+    unsigned int length;
 
151
     FD fd;
 
152
     
 
153
+#if defined(USE_IPV6)
 
154
+    if (strchr(ipstring, ':'))
 
155
+       return do_listen6(ipstring, lport, backlog, aport);
 
156
+#endif
 
157
+
 
158
     if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_FD) {
 
159
        DEBUGF(("Error calling socket()\n"));
 
160
        return fd;
 
161
@@ -1628,6 +1670,145 @@
 
162
     return fd;
 
163
 }
 
164
 
 
165
+#if defined(USE_IPV6)
 
166
+static FD do_connect6(char *lipstring, int lport, char *fipstring, int fport)
 
167
+{
 
168
+    struct sockaddr_in6 sock_addr;
 
169
+    FD fd;
 
170
+
 
171
+    if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) == INVALID_FD) {
 
172
+       DEBUGF(("Error calling socket()\n"));
 
173
+       return fd;
 
174
+    }
 
175
+    if (check_num_sock_fds(fd) < 0) 
 
176
+       return INVALID_FD;
 
177
+    DEBUGF(("  fd = %d\n", fd));
 
178
+
 
179
+    memset(&sock_addr, 0, sizeof(sock_addr));
 
180
+    /* local */
 
181
+    if (inet_pton(AF_INET6, lipstring, &sock_addr.sin6_addr) <= 0) {
 
182
+       DEBUGF(("Error in inet_pton(): lipstring = %s\n", lipstring));
 
183
+       safe_close(fd);
 
184
+       sock_set_errno(ERRNO_ADDRNOTAVAIL);
 
185
+       return INVALID_FD;
 
186
+    }
 
187
+    sock_addr.sin6_family = AF_INET6;
 
188
+    sock_addr.sin6_port = htons(lport);
 
189
+    if(bind(fd, (struct sockaddr*) &sock_addr, sizeof(sock_addr)) < 0) {
 
190
+       DEBUGF(("Error in bind()\n"));
 
191
+       safe_close(fd);
 
192
+       /* XXX Set error code for bind error */
 
193
+       return INVALID_FD;
 
194
+    }
 
195
+
 
196
+    /* foreign */
 
197
+    memset(&sock_addr, 0, sizeof(sock_addr));
 
198
+    if (inet_pton(AF_INET6, fipstring, &sock_addr.sin6_addr) <= 0) {
 
199
+       DEBUGF(("Error in inet_pton(): fipstring = %s\n", fipstring));
 
200
+       safe_close(fd);
 
201
+       sock_set_errno(ERRNO_ADDRNOTAVAIL);
 
202
+       return INVALID_FD;
 
203
+    }
 
204
+    sock_addr.sin6_family = AF_INET6;
 
205
+    sock_addr.sin6_port = htons(fport);
 
206
+
 
207
+    SET_NONBLOCKING(fd);
 
208
+
 
209
+    if(connect(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) < 0) {
 
210
+       if (sock_errno() != ERRNO_PROGRESS && /* UNIX */
 
211
+           sock_errno() != ERRNO_BLOCK) { /* WIN32 */
 
212
+           DEBUGF(("Error in connect()\n"));
 
213
+           safe_close(fd);
 
214
+           return INVALID_FD;
 
215
+       }
 
216
+    }
 
217
+    return fd;
 
218
+}
 
219
+
 
220
+static FD do_listen6(char *ipstring, int lport, int backlog, int *aport)
 
221
+{
 
222
+    static int one = 1;                /* Type must be int, not long */
 
223
+    struct sockaddr_in6 sock_addr;
 
224
+    socklen_t length;
 
225
+    FD fd;
 
226
+    
 
227
+    if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) == INVALID_FD) {
 
228
+       DEBUGF(("Error calling socket()\n"));
 
229
+       return fd;
 
230
+    }
 
231
+    if (check_num_sock_fds(fd) < 0) 
 
232
+       return INVALID_FD;
 
233
+    DEBUGF(("  fd = %d\n", fd));
 
234
+    memset(&sock_addr, 0, sizeof(sock_addr));
 
235
+    if (inet_pton(AF_INET6, ipstring, &sock_addr.sin6_addr) <= 0) {
 
236
+       DEBUGF(("Error in inet_pton(): ipstring = %s\n", ipstring));
 
237
+       safe_close(fd);
 
238
+       sock_set_errno(ERRNO_ADDRNOTAVAIL);
 
239
+       return INVALID_FD;
 
240
+    }
 
241
+    sock_addr.sin6_family = AF_INET6;
 
242
+    sock_addr.sin6_port = htons(lport);
 
243
+
 
244
+    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
 
245
+
 
246
+    if(bind(fd, (struct sockaddr*) &sock_addr, sizeof(sock_addr)) < 0) {
 
247
+       DEBUGF(("Error in bind()\n"));
 
248
+       safe_close(fd);
 
249
+       return INVALID_FD;
 
250
+    }
 
251
+    if (listen(fd, backlog) < 0) {
 
252
+       DEBUGF(("Error in listen()\n"));
 
253
+       safe_close(fd);
 
254
+       return INVALID_FD;
 
255
+    }
 
256
+    /* find out assigned local port number */
 
257
+    length = sizeof(sock_addr);
 
258
+    if (getsockname(fd, (struct sockaddr *)&sock_addr, &length) < 0) {
 
259
+       DEBUGF(("Error in getsockname()\n"));
 
260
+       safe_close(fd);
 
261
+       return INVALID_FD;
 
262
+    }
 
263
+    if (aport)
 
264
+       *aport = ntohs(sock_addr.sin6_port);
 
265
+    return fd;
 
266
+}
 
267
+
 
268
+static int reply_sockaddr(int cmd, int fd, const struct sockaddr *sa,
 
269
+                         socklen_t size)
 
270
+{
 
271
+    char addr[INET6_ADDRSTRLEN+1] = "";
 
272
+    char port[10] = "";
 
273
+    int res;
 
274
+
 
275
+    res = getnameinfo(sa, size,
 
276
+                     addr, sizeof(addr), port, sizeof(port),
 
277
+                     NI_NUMERICHOST | NI_NUMERICSERV);
 
278
+    if (res) {
 
279
+       if (res != EAI_SYSTEM) {
 
280
+           sock_set_errno(ERRNO_INVAL);
 
281
+       }
 
282
+       return reply(cmd, "4s", fd, psx_errstr());
 
283
+    } else {
 
284
+       return reply(cmd, "42s", fd, atoi(port), addr);
 
285
+    }
 
286
+}
 
287
+
 
288
+static int ss_getport(const struct sockaddr *sa, socklen_t size)
 
289
+{
 
290
+    char port[10] = "";
 
291
+    int res;
 
292
+
 
293
+    res = getnameinfo(sa, size,
 
294
+                     NULL, 0, port, sizeof(port), NI_NUMERICSERV);
 
295
+    if (res) {
 
296
+       return -1;
 
297
+    } else {
 
298
+       return atoi(port);
 
299
+    }
 
300
+}
 
301
+#endif
 
302
+
 
303
+
 
304
 static Connection *new_connection(int state, FD fd)
 
305
 {
 
306
     Connection *cp;
 
307
--- erlang-12.b.3-dfsg.orig/lib/ssl/src/ssl_broker.erl
 
308
+++ erlang-12.b.3-dfsg/lib/ssl/src/ssl_broker.erl
 
309
@@ -483,7 +483,7 @@
 
310
     debug(St, "peername: client = ~w~n", [Client]),
 
311
     Reply = case ssl_server:peername(St#st.fd) of
 
312
                {ok, {Address, Port}} ->
 
313
-                   {ok, At} = inet_parse:ipv4_address(Address),
 
314
+                   {ok, At} = inet_parse:address(Address),
 
315
                    {ok, {At, Port}};
 
316
                Error ->
 
317
                    Error
 
318
@@ -540,7 +540,7 @@
 
319
     debug(St, "sockname: client = ~w~n", [Client]),
 
320
     Reply = case ssl_server:sockname(St#st.fd) of
 
321
                {ok, {Address, Port}} ->
 
322
-                   {ok, At} = inet_parse:ipv4_address(Address),
 
323
+                   {ok, At} = inet_parse:address(Address),
 
324
                    {ok, {At, Port}};
 
325
                Error ->
 
326
                    Error
 
327
@@ -703,7 +703,8 @@
 
328
     SSLOpts = get_ssl_opts(Opts),
 
329
     FlagStr =mk_ssl_optstr(SSLOpts),
 
330
     BackLog = get_backlog(LOpts),
 
331
-    IP = get_ip(LOpts),
 
332
+    Family = get_family(Opts),
 
333
+    IP = get_ip(LOpts, Family),
 
334
     case ssl_server:listen_prim(ServerName, IP, Port, FlagStr, BackLog) of
 
335
        {ok, ListenFd, _Port0} ->
 
336
            ThisSocket = #sslsocket{fd = ListenFd, pid = self()},
 
337
@@ -726,10 +727,11 @@
 
338
     COpts = get_tcp_connect_opts(Opts),
 
339
     SSLOpts = get_ssl_opts(Opts),
 
340
     FlagStr = mk_ssl_optstr(SSLOpts),
 
341
-    case inet:getaddr(FAddress, inet) of
 
342
+    Family = get_family(Opts),
 
343
+    case inet:getaddr(FAddress, Family) of
 
344
        {ok, FIP} ->
 
345
            %% Timeout is gen_server timeout - hence catch
 
346
-           LIP = get_ip(COpts),
 
347
+           LIP = get_ip(COpts, Family),
 
348
            LPort = get_port(COpts),
 
349
            case (catch ssl_server:connect_prim(ServerName, 
 
350
                                                LIP, LPort, FIP, FPort, 
 
351
@@ -1016,8 +1018,13 @@
 
352
 get_backlog(Opts) ->
 
353
     get_tagged_opt(backlog, Opts, ?DEF_BACKLOG).
 
354
 
 
355
-get_ip(Opts) ->
 
356
-    get_tagged_opt(ip, Opts, {0, 0, 0, 0}).
 
357
+get_ip(Opts, Family) ->
 
358
+    DefaultIp =
 
359
+       case Family of
 
360
+           inet -> {0, 0, 0, 0};
 
361
+           inet6 -> {0, 0, 0, 0, 0, 0, 0, 0}
 
362
+       end,
 
363
+    get_tagged_opt(ip, Opts, DefaultIp).
 
364
 
 
365
 get_port(Opts) ->
 
366
     get_tagged_opt(port, Opts, 0).
 
367
@@ -1025,6 +1032,9 @@
 
368
 get_nodelay(Opts) ->
 
369
     get_tagged_opt(nodelay, Opts, empty).
 
370
 
 
371
+get_family(Opts) ->
 
372
+    get_tagged_opt(family, transform_opts(Opts), inet).
 
373
+
 
374
 %%
 
375
 %% add_default_*_opts(Opts) -> NOpts
 
376
 %%
 
377
@@ -1073,6 +1083,8 @@
 
378
 transform_opt(binary) ->               [{mode, binary}];
 
379
 transform_opt(list) ->                         [{mode, list}];
 
380
 transform_opt({packet, raw}) ->                [{packet, 0}];
 
381
+transform_opt(inet) ->                 [{family, inet}];
 
382
+transform_opt(inet6) ->                        [{family, inet6}];
 
383
 transform_opt(raw) ->                  [];
 
384
 transform_opt(Opt) ->                  [Opt].
 
385
 
 
386
@@ -1080,10 +1092,10 @@
 
387
 %% only.
 
388
 
 
389
 is_connect_opt(Opt) ->
 
390
-    is_tcp_connect_opt(Opt) or is_ssl_opt(Opt).
 
391
+    is_tcp_connect_opt(Opt) or is_ssl_opt(Opt) or is_family_opt(Opt).
 
392
 
 
393
 is_listen_opt(Opt) ->
 
394
-    is_tcp_listen_opt(Opt) or is_ssl_opt(Opt).
 
395
+    is_tcp_listen_opt(Opt) or is_ssl_opt(Opt) or is_family_opt(Opt).
 
396
 
 
397
 is_tcp_accept_opt(Opt) ->
 
398
     is_tcp_gen_opt(Opt).
 
399
@@ -1139,6 +1151,10 @@
 
400
 is_ssl_opt({cachetimeout, Timeout}) when Timeout >= 0 -> true;
 
401
 is_ssl_opt(_Opt) -> false.
 
402
 
 
403
+is_family_opt({family, inet}) -> true;
 
404
+is_family_opt({family, inet6}) -> true;
 
405
+is_family_opt(_Opt) -> false.
 
406
+
 
407
 %% Various types
 
408
 is_string(String) when is_list(String) ->
 
409
     lists:all(fun (C) when is_integer(C), 0 =< C, C =< 255 -> true; 
 
410
@@ -1149,11 +1165,20 @@
 
411
 
 
412
 is_ip_address(Addr) when is_tuple(Addr), size(Addr) == 4 ->
 
413
     is_string(tuple_to_list(Addr));
 
414
+is_ip_address(Addr) when is_tuple(Addr), size(Addr) == 8 ->
 
415
+    is_ip6_string(tuple_to_list(Addr));
 
416
 is_ip_address(Addr) when is_list(Addr) ->
 
417
     is_string(Addr);
 
418
 is_ip_address(_) ->
 
419
     false.
 
420
 
 
421
+is_ip6_string(String) when is_list(String) ->
 
422
+    lists:all(fun (C) when is_integer(C), 0 =< C, C =< 65535 -> true; 
 
423
+                 (_C) -> false end, 
 
424
+             String);
 
425
+is_ip6_string(_) ->
 
426
+    false.
 
427
+
 
428
 get_tagged_opt(Tag, Opts, Default) ->
 
429
     case lists:keysearch(Tag, 1, Opts) of
 
430
        {value, {_, Value}} ->
 
431
--- erlang-12.b.3-dfsg.orig/lib/ssl/src/ssl_prim.erl
 
432
+++ erlang-12.b.3-dfsg/lib/ssl/src/ssl_prim.erl
 
433
@@ -124,7 +124,7 @@
 
434
 peername(St) when record(St, st), St#st.status =:= open  ->
 
435
     case ssl_server:peername_prim(ssl_server_prim, St#st.fd) of
 
436
        {ok, {Address, Port}} ->
 
437
-           {ok, At} = inet_parse:ipv4_address(Address),
 
438
+           {ok, At} = inet_parse:address(Address),
 
439
            {ok, {At, Port}};
 
440
        Error ->
 
441
            Error
 
442
@@ -136,7 +136,7 @@
 
443
 sockname(St) when record(St, st), St#st.status =:= open  ->
 
444
     case ssl_server:sockname_prim(ssl_server_prim, St#st.fd) of
 
445
        {ok, {Address, Port}} ->
 
446
-           {ok, At} = inet_parse:ipv4_address(Address),
 
447
+           {ok, At} = inet_parse:address(Address),
 
448
            {ok, {At, Port}};
 
449
        Error ->
 
450
            Error
 
451
--- erlang-12.b.3-dfsg.orig/lib/ssl/src/ssl_server.erl
 
452
+++ erlang-12.b.3-dfsg/lib/ssl/src/ssl_server.erl
 
453
@@ -1375,7 +1375,10 @@
 
454
 
 
455
 ip_to_string({A,B,C,D}) ->
 
456
     [integer_to_list(A),$.,integer_to_list(B),$.,
 
457
-     integer_to_list(C),$.,integer_to_list(D)].
 
458
+     integer_to_list(C),$.,integer_to_list(D)];
 
459
+
 
460
+ip_to_string(Addr) when is_tuple(Addr), size(Addr) == 8 ->
 
461
+    inet_parse:ntoa(Addr).
 
462
 
 
463
 debug(St, Format, Args) ->
 
464
     debug1(St#st.debug, Format, Args).