tlsio function;
This commit is contained in:
		
							parent
							
								
									f6e850b8f2
								
							
						
					
					
						commit
						3aa1f97545
					
				| @ -27,6 +27,11 @@ struct tlsport { | ||||
|   SSL_CTX *sslctx; | ||||
| }; | ||||
| 
 | ||||
| typedef enum { | ||||
|   TLSIO_READ = 1, | ||||
|   TLSIO_WRITE = 2, | ||||
| } tls_io_dir_t; | ||||
| 
 | ||||
| /* this function shall be called before main loop */ | ||||
| int ssllib_init(void); | ||||
| 
 | ||||
| @ -45,4 +50,9 @@ int tls_connect(const char *, const char *, struct tlsport *); | ||||
|  */ | ||||
| int tls_close(struct tlsport *); | ||||
| 
 | ||||
| /* read or write (depends on tls_io_dir_t) data via tlsport
 | ||||
|  * returns amount of bytes ridden or written, -1 in case of error | ||||
|  */ | ||||
| ssize_t tls_io(struct tlsport *, void *, size_t, tls_io_dir_t); | ||||
| 
 | ||||
| #endif /* __TLSPORT_H__ */ | ||||
|  | ||||
							
								
								
									
										81
									
								
								src/tls.c
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/tls.c
									
									
									
									
									
								
							| @ -186,3 +186,84 @@ int tls_close(struct tlsport *p) | ||||
| 
 | ||||
|   return e; | ||||
| } | ||||
| 
 | ||||
| ssize_t tls_io(struct tlsport *p, void *buf, size_t bf_size, tls_io_dir_t dr) | ||||
| { | ||||
|   int sel_read, sel_write; | ||||
|   int r, w = 0; | ||||
|   fd_set readfd, writefd; | ||||
| 
 | ||||
|   if(!p || !buf) { | ||||
|     errno = EINVAL; | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   if(!bf_size) { | ||||
|     errno = EINVAL; | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|  ssllib_io: | ||||
|   sel_read = sel_write = 0; | ||||
|   do { | ||||
|     switch(dr) { | ||||
|     case TLSIO_READ: | ||||
|       r = SSL_read(p->ssl, buf, bf_size); | ||||
|       if(r > 0) return r; | ||||
|       break; | ||||
|     case TLSIO_WRITE: | ||||
|       r = SSL_write(p->ssl, (char *)buf + sizeof(char)*w, bf_size - w); | ||||
|       if(r == (bf_size - w)) return bf_size; | ||||
|       else if(r > 0) w += r; | ||||
|       break; | ||||
|     default: | ||||
|       errno = EINVAL; | ||||
|       return -1; | ||||
|     } | ||||
| 
 | ||||
|     switch(SSL_get_error(p->ssl, r)) { | ||||
|     case SSL_ERROR_NONE: | ||||
|       break; | ||||
|     case SSL_ERROR_WANT_READ: | ||||
|       sel_read = 1; /* is required to wait during read */ break; | ||||
|     case SSL_ERROR_WANT_WRITE: | ||||
|       sel_write = 1; /* is required to wait during write */ break; | ||||
|     case SSL_ERROR_WANT_CONNECT: | ||||
|     case SSL_ERROR_WANT_ACCEPT: | ||||
|       break; | ||||
|     case SSL_ERROR_SYSCALL: | ||||
|       if(errno == EAGAIN || errno == EINTR) break; | ||||
|     case SSL_ERROR_SSL: | ||||
|     case SSL_ERROR_ZERO_RETURN: /* expected close */ | ||||
|     default: | ||||
|       return -1; | ||||
|       break; | ||||
|     } | ||||
|   } while(SSL_pending(p->ssl) && !sel_read); | ||||
| 
 | ||||
|   /* wait to read */ | ||||
|   if(r != SSL_ERROR_NONE && sel_read) { | ||||
|     FD_ZERO(&readfd); | ||||
|     FD_SET(p->fd, &readfd); | ||||
| 
 | ||||
|   ioread_select: | ||||
|     r = select(p->fd + 1, &readfd, NULL, NULL, NULL); | ||||
|     if(r <= 0) { | ||||
|       if(errno == EAGAIN || errno == EINTR) goto ioread_select; | ||||
|       else return -1; | ||||
|     } else if(FD_ISSET(p->fd, &readfd)) goto ssllib_io; | ||||
|   } | ||||
| 
 | ||||
|   /* wait to write */ | ||||
|   if(r != SSL_ERROR_NONE && sel_write) { | ||||
|     FD_ZERO(&readfd); | ||||
|     FD_ZERO(&writefd); | ||||
|     FD_SET(p->fd, &readfd); | ||||
|     FD_SET(p->fd, &writefd); | ||||
| 
 | ||||
|     r = select(p->fd + 1, &readfd, &writefd, NULL, NULL); | ||||
|     if(r && FD_ISSET(p->fd, &writefd)) goto ssllib_io; | ||||
|   } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user