| 139 | | static GIOStatus (GIOChannel *handle, const gchar *buf, gsize len, gsize *ret, GError **gerr) |
| 140 | | { |
| 141 | | GIOSSLChannel *chan = (GIOSSLChannel *)handle; |
| 142 | | gint ret1, err; |
| 143 | | const char *errstr; |
| 144 | | |
| 145 | | ret1 = SSL_write(chan->ssl, (const char *)buf, len); |
| 146 | | if(ret1 <= 0) |
| 147 | | { |
| 148 | | *ret = 0; |
| 149 | | err = SSL_get_error(chan->ssl, ret1); |
| 150 | | if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
|
| 151 | | return G_IO_STATUS_AGAIN; |
| 152 | | else if(err == SSL_ERROR_ZERO_RETURN)
|
| 153 | | errstr = "server closed connection"; |
| 154 | | else if (err == SSL_ERROR_SYSCALL)
|
| 155 | | { |
| 156 | | errstr = ERR_reason_error_string(ERR_get_error()); |
| 157 | | if (errstr == NULL && ret1 == -1)
|
| 158 | | errstr = strerror(errno); |
| 159 | | if (errstr == NULL)
|
| 160 | | errstr = "server closed connection unexpectedly"; |
| 161 | | } |
| 162 | | else |
| 163 | | { |
| 164 | | errstr = ERR_reason_error_string(ERR_get_error()); |
| 165 | | if (errstr == NULL)
|
| 166 | | errstr = "unknown SSL error"; |
| 167 | | } |
| 168 | | g_warning("SSL write error: %s", errstr);
|
| 169 | | *gerr = g_error_new_literal(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED,
|
| 170 | | errstr); |
| 171 | | return G_IO_STATUS_ERROR; |
| 172 | | } |
| 173 | | else |
| 174 | | { |
| 175 | | *ret = ret1; |
| 176 | | return G_IO_STATUS_NORMAL; |
| 177 | | } |
| 178 | | |
| 179 | | return G_IO_STATUS_ERROR; |
| 180 | | } |