Hi there,
I've attached a small patch for the openssl egg that adds another error status.
This status is 'ssl-eof when the error is SSL_ERR_SYSCALL but the return code
is zero.
According to the OpenSSL docs[1] under the BUGS section:
> The SSL_ERROR_SYSCALL eith errno value of 0 indicates unexpected EOF from the
> peer.
> This will be properly reported as SSL_ERROR_SSL with reason code
> SSL_R_UNEXPECTED_EOF_WHILE_READING in the OpenSSL 3.0 release because it is
> truly a
> TLS protocol error to terminate the connection without a SSL_shutdown().
>
> The issue is kept unfixed in OpenSSL 1.1.1 releases because many applications
> which
> choose to ignore this protocol error depend on the existing way of reporting
> the error.
Basically this gives the user the option to treat it is as an !#eof instead of
a fatal error.
I've been running into this issue while building a Gemini[2] client where there
are a
plethora of servers written by hobbyists. Also, the protocol does not have a
Content-Length header,
which means I can't avoid this issue by simply not reading past the end.
- Harley
[1] https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
[2] https://gemini.circumlunar.space/docs/specification.html
Index: openssl.scm
===
--- openssl.scm (revision 39418)
+++ openssl.scm (working copy)
@@ -256,50 +256,50 @@
'want-accept)
((eq? x (foreign-value "SSL_ERROR_WANT_X509_LOOKUP" int))
'want-X509-lookup)
- ((eq? x (foreign-value "SSL_ERROR_SYSCALL" int))
-'syscall)
- ((eq? x (foreign-value "SSL_ERROR_SSL" int))
+ ((eq? x (foreign-value "SSL_ERROR_SYSCALL" int))
+(if (zero? ret) 'ssl-eof 'syscall))
+ ((eq? x (foreign-value "SSL_ERROR_SSL" int))
'ssl)
- (else
+ (else
#f)
(apply ssl-abort loc sym args)
-(define (ssl-set-tlsext-hostname! ssl hostname)
- (ssl-clear-error)
- (ssl-result-or-abort
- 'ssl-set-tlsext-hostname! ssl
- ((foreign-lambda int "SSL_set_tlsext_host_name" c-pointer c-string)
-ssl hostname) #f
- hostname)
- (void))
+ (define (ssl-set-tlsext-hostname! ssl hostname)
+(ssl-clear-error)
+(ssl-result-or-abort
+ 'ssl-set-tlsext-hostname! ssl
+ ((foreign-lambda int "SSL_set_tlsext_host_name" c-pointer c-string)
+ ssl hostname) #f
+ hostname)
+(void))
-(define (ssl-set-fd! ssl fd)
- (ssl-clear-error)
- (ssl-result-or-abort
- 'ssl-set-fd! ssl
- ((foreign-lambda int "SSL_set_fd" c-pointer int) ssl fd) #f
- fd)
- (void))
+ (define (ssl-set-fd! ssl fd)
+(ssl-clear-error)
+(ssl-result-or-abort
+ 'ssl-set-fd! ssl
+ ((foreign-lambda int "SSL_set_fd" c-pointer int) ssl fd) #f
+ fd)
+(void))
-(define (ssl-shutdown ssl)
- (ssl-clear-error)
- (let ((ret
-((foreign-lambda*
- scheme-object ((c-pointer ssl))
- "int ret;\n"
- "switch (ret = SSL_shutdown((SSL *)ssl)) {\n"
- "case 0: return(C_SCHEME_FALSE);\n"
- "case 1: return(C_SCHEME_TRUE);\n"
- "default: return(C_fix(ret));\n"
- "}\n") ssl)))
-(if (fixnum? ret)
- (ssl-result-or-abort 'ssl-shutdown ssl ret #t)
- ret)))
+ (define (ssl-shutdown ssl)
+(ssl-clear-error)
+(let ((ret
+ ((foreign-lambda*
+scheme-object ((c-pointer ssl))
+"int ret;\n"
+"switch (ret = SSL_shutdown((SSL *)ssl)) {\n"
+"case 0: return(C_SCHEME_FALSE);\n"
+"case 1: return(C_SCHEME_TRUE);\n"
+"default: return(C_fix(ret));\n"
+"}\n") ssl)))
+ (if (fixnum? ret)
+ (ssl-result-or-abort 'ssl-shutdown ssl ret #t)
+ ret)))
-(define (ssl-read! ssl buffer offset size)
- (ssl-clear-error)
- (let ((ret
- ((foreign-lambda*
+ (define (ssl-read! ssl buffer offset size)
+(ssl-clear-error)
+(let ((ret
+ ((foreign-lambda*
scheme-object ((c-pointer ssl) (scheme-pointer buf) (int offset)
(int size))
"int ret;\n"
"switch (ret = SSL_read((SSL *)ssl, (char *)buf + offset, size))
{\n"
@@ -307,178 +307,178 @@
" C_SCHEME_END_OF_FILE : C_fix(0));\n"
"default: return(C_fix(ret));\n"
"}\n")
-ssl buffer offset size)))
-(cond ((eof-object? ret) 0)
- ((fx> ret 0) ret)
- (else (ssl-result-or-abort 'ssl-read! ssl ret #t)
+ ssl buffer offset size)))
+ (cond ((eof-object? ret) 0)
+ ((fx> ret 0) ret)
+ (else (ssl-result-or-abort 'ssl-read! ssl ret #t)
-(define (ssl-get-char ssl)
- (ssl-clear-error)
- (let ((ret
-((foreign-lambda*
- scheme-object ((c-pointer ssl))
- "unsigned char ch;\n"
- "int ret;\n"
- "switch