Use KISS framing for raw sockets
Use KISS framing for raw sockets to avoid multiple write() calls from being buffered, which caused read() on the other end of a file descriptor to read more than frame at once
This commit is contained in:
		
							parent
							
								
									b281925eba
								
							
						
					
					
						commit
						ebbfb50b1c
					
				
					 3 changed files with 32 additions and 22 deletions
				
			
		|  | @ -33,8 +33,7 @@ int main(int argc, char **argv) { | ||||||
|     patty_ax25_call_setsockopt_if ifreq; |     patty_ax25_call_setsockopt_if ifreq; | ||||||
| 
 | 
 | ||||||
|     int fd, |     int fd, | ||||||
|         sock, |         sock; | ||||||
|         pty; |  | ||||||
| 
 | 
 | ||||||
|     patty_ax25_addr peer; |     patty_ax25_addr peer; | ||||||
|     char path[PATTY_AX25_SOCK_PATH_SIZE]; |     char path[PATTY_AX25_SOCK_PATH_SIZE]; | ||||||
|  | @ -42,6 +41,8 @@ int main(int argc, char **argv) { | ||||||
|     uint8_t buf[4096]; |     uint8_t buf[4096]; | ||||||
|     ssize_t readlen; |     ssize_t readlen; | ||||||
| 
 | 
 | ||||||
|  |     patty_kiss_tnc *raw; | ||||||
|  | 
 | ||||||
|     if (argc != 2) { |     if (argc != 2) { | ||||||
|         usage(argc, argv, "No patty socket provided"); |         usage(argc, argv, "No patty socket provided"); | ||||||
|     } |     } | ||||||
|  | @ -79,14 +80,14 @@ int main(int argc, char **argv) { | ||||||
|         goto error_call_setsockopt; |         goto error_call_setsockopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((pty = open(path, O_RDWR)) < 0) { |     if ((raw = patty_kiss_tnc_new(path)) == NULL) { | ||||||
|         fprintf(stderr, "%s: %s: %s: %s\n", |         fprintf(stderr, "%s: %s: %s: %s\n", | ||||||
|             argv[0], path, "open()", strerror(errno)); |             argv[0], path, "patty_kiss_tnc_new()", strerror(errno)); | ||||||
| 
 | 
 | ||||||
|         goto error_open_pty; |         goto error_kiss_tnc_new; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while ((readlen = read(pty, buf, sizeof(buf))) > 0) { |     while ((readlen = patty_kiss_tnc_recv(raw, buf, sizeof(buf), NULL)) > 0) { | ||||||
|         patty_ax25_frame frame; |         patty_ax25_frame frame; | ||||||
| 
 | 
 | ||||||
|         if (patty_ax25_frame_decode(&frame, PATTY_AX25_FRAME_NORMAL, buf, readlen) < 0) { |         if (patty_ax25_frame_decode(&frame, PATTY_AX25_FRAME_NORMAL, buf, readlen) < 0) { | ||||||
|  | @ -104,7 +105,7 @@ int main(int argc, char **argv) { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     close(pty); |     patty_kiss_tnc_destroy(raw); | ||||||
| 
 | 
 | ||||||
|     patty_ax25_call_close(fd, sock); |     patty_ax25_call_close(fd, sock); | ||||||
| 
 | 
 | ||||||
|  | @ -114,7 +115,9 @@ int main(int argc, char **argv) { | ||||||
| 
 | 
 | ||||||
| error_print_frame: | error_print_frame: | ||||||
| error_ax25_frame_decode: | error_ax25_frame_decode: | ||||||
| error_open_pty: |     patty_kiss_tnc_destroy(raw); | ||||||
|  | 
 | ||||||
|  | error_kiss_tnc_new: | ||||||
|     patty_ax25_call_close(fd, sock); |     patty_ax25_call_close(fd, sock); | ||||||
| 
 | 
 | ||||||
| error_call_setsockopt: | error_call_setsockopt: | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								src/if.c
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/if.c
									
										
									
									
									
								
							|  | @ -273,15 +273,21 @@ error_ntop: | ||||||
| 
 | 
 | ||||||
| int patty_ax25_if_promisc_add(patty_ax25_if *iface, | int patty_ax25_if_promisc_add(patty_ax25_if *iface, | ||||||
|                               int fd) { |                               int fd) { | ||||||
|  |     patty_kiss_tnc *tnc; | ||||||
|  | 
 | ||||||
|     if (patty_dict_get(iface->promisc_fds, (uint32_t)fd)) { |     if (patty_dict_get(iface->promisc_fds, (uint32_t)fd)) { | ||||||
|         errno = EEXIST; |         errno = EEXIST; | ||||||
| 
 | 
 | ||||||
|         goto error_exists; |         goto error_exists; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if ((tnc = patty_kiss_tnc_new_fd(fd)) == NULL) { | ||||||
|  |         goto error_kiss_tnc_new_fd; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (patty_dict_set(iface->promisc_fds, |     if (patty_dict_set(iface->promisc_fds, | ||||||
|                        (uint32_t)fd, |                        (uint32_t)fd, | ||||||
|                        NULL + fd) == NULL) { |                        tnc) == NULL) { | ||||||
|         errno = ENOMEM; |         errno = ENOMEM; | ||||||
| 
 | 
 | ||||||
|         goto error_dict_set; |         goto error_dict_set; | ||||||
|  | @ -290,20 +296,26 @@ int patty_ax25_if_promisc_add(patty_ax25_if *iface, | ||||||
|     return 0; |     return 0; | ||||||
| 
 | 
 | ||||||
| error_dict_set: | error_dict_set: | ||||||
|  |     patty_kiss_tnc_destroy(tnc); | ||||||
|  | 
 | ||||||
|  | error_kiss_tnc_new_fd: | ||||||
| error_exists: | error_exists: | ||||||
|     return -1; |     return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int patty_ax25_if_promisc_delete(patty_ax25_if *iface, | int patty_ax25_if_promisc_delete(patty_ax25_if *iface, | ||||||
|                                  int fd) { |                                  int fd) { | ||||||
|     if (patty_dict_delete(iface->promisc_fds, |     patty_kiss_tnc *tnc; | ||||||
|                           (uint32_t)fd) < 0) { | 
 | ||||||
|  |     if ((tnc = patty_dict_get(iface->promisc_fds, (uint32_t)fd)) == NULL) { | ||||||
|         errno = ENOENT; |         errno = ENOENT; | ||||||
| 
 | 
 | ||||||
|         goto error_notfound; |         goto error_notfound; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return 0; |     patty_kiss_tnc_destroy(tnc); | ||||||
|  | 
 | ||||||
|  |     return patty_dict_delete(iface->promisc_fds, (uint32_t)fd); | ||||||
| 
 | 
 | ||||||
| error_notfound: | error_notfound: | ||||||
|     return -1; |     return -1; | ||||||
|  | @ -318,17 +330,10 @@ struct promisc_frame { | ||||||
| static int handle_promisc_frame(uint32_t key, | static int handle_promisc_frame(uint32_t key, | ||||||
|                                 void *value, |                                 void *value, | ||||||
|                                 void *ctx) { |                                 void *ctx) { | ||||||
|     int fd = (int)key; |     patty_kiss_tnc *tnc = value; | ||||||
|     struct promisc_frame *frame = ctx; |     struct promisc_frame *frame = ctx; | ||||||
| 
 | 
 | ||||||
|     if (write(fd, frame->buf, frame->len) < 0) { |     return patty_kiss_tnc_send(tnc, frame->buf, frame->len, 0); | ||||||
|         goto error_write; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return tcdrain(fd); |  | ||||||
| 
 |  | ||||||
| error_write: |  | ||||||
|     return -1; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ssize_t patty_ax25_if_recv(patty_ax25_if *iface, | ssize_t patty_ax25_if_recv(patty_ax25_if *iface, | ||||||
|  |  | ||||||
|  | @ -183,7 +183,9 @@ ssize_t patty_kiss_tnc_recv(patty_kiss_tnc *tnc, | ||||||
|                 goto error_io; |                 goto error_io; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             *port = PATTY_KISS_COMMAND_PORT(c); |             if (port) { | ||||||
|  |                 *port = PATTY_KISS_COMMAND_PORT(c); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             flags |= KISS_COMMAND; |             flags |= KISS_COMMAND; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue