Implement ring buffer for sock sent frames
Implement ring buffer for frames sent in a SABM or SABME session, facilitating the ability to retransmit select frames upon request, retaining a copy of the full frame and its transmitted size
This commit is contained in:
		
							parent
							
								
									6df612b910
								
							
						
					
					
						commit
						c26c7509f4
					
				
					 3 changed files with 85 additions and 20 deletions
				
			
		| 
						 | 
					@ -2,6 +2,8 @@
 | 
				
			||||||
#define _PATTY_AX25_SOCK_H
 | 
					#define _PATTY_AX25_SOCK_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PATTY_AX25_SOCK_BUFSZ      4096
 | 
					#define PATTY_AX25_SOCK_BUFSZ      4096
 | 
				
			||||||
 | 
					#define PATTY_AX25_SOCK_SLOTS_SABM    8
 | 
				
			||||||
 | 
					#define PATTY_AX25_SOCK_SLOTS_SABME 128
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum patty_ax25_sock_type {
 | 
					enum patty_ax25_sock_type {
 | 
				
			||||||
    PATTY_AX25_SOCK_STREAM,
 | 
					    PATTY_AX25_SOCK_STREAM,
 | 
				
			||||||
| 
						 | 
					@ -26,6 +28,11 @@ enum patty_ax25_sock_opt {
 | 
				
			||||||
    PATTY_AX25_SOCK_IF
 | 
					    PATTY_AX25_SOCK_IF
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _patty_ax25_sock_tx_slot {
 | 
				
			||||||
 | 
					    size_t len;
 | 
				
			||||||
 | 
					    uint8_t buf[PATTY_AX25_SOCK_BUFSZ];
 | 
				
			||||||
 | 
					} patty_ax25_sock_tx_slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _patty_ax25_sock {
 | 
					typedef struct _patty_ax25_sock {
 | 
				
			||||||
    enum patty_ax25_proto       proto;
 | 
					    enum patty_ax25_proto       proto;
 | 
				
			||||||
    enum patty_ax25_sock_type   type;
 | 
					    enum patty_ax25_sock_type   type;
 | 
				
			||||||
| 
						 | 
					@ -46,8 +53,8 @@ typedef struct _patty_ax25_sock {
 | 
				
			||||||
    int fd;
 | 
					    int fd;
 | 
				
			||||||
    char path[PATTY_AX25_SOCK_PATH_SIZE];
 | 
					    char path[PATTY_AX25_SOCK_PATH_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void *buf;
 | 
					    void *rx_buf;
 | 
				
			||||||
    size_t bufsz;
 | 
					    patty_ax25_sock_tx_slot *tx_slots;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    patty_ax25_if *iface;
 | 
					    patty_ax25_if *iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +72,9 @@ void patty_ax25_sock_reset(patty_ax25_sock *sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void patty_ax25_sock_destroy(patty_ax25_sock *sock);
 | 
					void patty_ax25_sock_destroy(patty_ax25_sock *sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int patty_ax25_sock_mode_set(patty_ax25_sock *sock,
 | 
				
			||||||
 | 
					                             enum patty_ax25_sock_mode mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *patty_ax25_sock_pty(patty_ax25_sock *sock);
 | 
					char *patty_ax25_sock_pty(patty_ax25_sock *sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int patty_ax25_sock_bind_if(patty_ax25_sock *sock,
 | 
					int patty_ax25_sock_bind_if(patty_ax25_sock *sock,
 | 
				
			||||||
| 
						 | 
					@ -80,6 +90,9 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
 | 
				
			||||||
                             void *info,
 | 
					                             void *info,
 | 
				
			||||||
                             size_t infolen);
 | 
					                             size_t infolen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock,
 | 
				
			||||||
 | 
					                               unsigned int seq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock,
 | 
					ssize_t patty_ax25_sock_send_rr(patty_ax25_sock *sock,
 | 
				
			||||||
                                enum patty_ax25_frame_cr cr);
 | 
					                                enum patty_ax25_frame_cr cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/server.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/server.c
									
										
									
									
									
								
							| 
						 | 
					@ -1047,6 +1047,8 @@ static int handle_sabm(patty_ax25_server *server,
 | 
				
			||||||
    patty_ax25_sock *local, *remote;
 | 
					    patty_ax25_sock *local, *remote;
 | 
				
			||||||
    patty_ax25_call_accept_response response;
 | 
					    patty_ax25_call_accept_response response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum patty_ax25_sock_mode mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((local = sock_by_addr(server->socks_pending_accept,
 | 
					    if ((local = sock_by_addr(server->socks_pending_accept,
 | 
				
			||||||
                              &frame->dest)) == NULL) {
 | 
					                              &frame->dest)) == NULL) {
 | 
				
			||||||
        return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
 | 
					        return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
 | 
				
			||||||
| 
						 | 
					@ -1060,11 +1062,15 @@ static int handle_sabm(patty_ax25_server *server,
 | 
				
			||||||
        goto error_sock_new;
 | 
					        goto error_sock_new;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mode = (frame->type == PATTY_AX25_FRAME_SABM)?
 | 
				
			||||||
 | 
					        PATTY_AX25_SOCK_SABM: PATTY_AX25_SOCK_SABME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    remote->status = PATTY_AX25_SOCK_ESTABLISHED;
 | 
					    remote->status = PATTY_AX25_SOCK_ESTABLISHED;
 | 
				
			||||||
    remote->iface  = iface;
 | 
					    remote->iface  = iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    remote->mode = (frame->type == PATTY_AX25_FRAME_SABM)?
 | 
					    if (patty_ax25_sock_mode_set(remote, mode) < 0) {
 | 
				
			||||||
        PATTY_AX25_SOCK_SABM: PATTY_AX25_SOCK_SABME;
 | 
					        goto error_sock_set_mode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    save_reply_addr(remote, frame);
 | 
					    save_reply_addr(remote, frame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1111,6 +1117,7 @@ error_reply_ua:
 | 
				
			||||||
error_sock_delete_by_addr:
 | 
					error_sock_delete_by_addr:
 | 
				
			||||||
error_sock_save_by_addrpair:
 | 
					error_sock_save_by_addrpair:
 | 
				
			||||||
error_sock_save_by_fd:
 | 
					error_sock_save_by_fd:
 | 
				
			||||||
 | 
					error_sock_set_mode:
 | 
				
			||||||
    patty_ax25_sock_destroy(remote);
 | 
					    patty_ax25_sock_destroy(remote);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_sock_new:
 | 
					error_sock_new:
 | 
				
			||||||
| 
						 | 
					@ -1380,7 +1387,7 @@ static int handle_sock(uint32_t key,
 | 
				
			||||||
        goto done;
 | 
					        goto done;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((len = read(sock->fd, sock->buf, sock->bufsz)) < 0) {
 | 
					    if ((len = read(sock->fd, sock->rx_buf, PATTY_AX25_SOCK_BUFSZ)) < 0) {
 | 
				
			||||||
        if (errno == EIO) {
 | 
					        if (errno == EIO) {
 | 
				
			||||||
            (void)sock_close(server, sock);
 | 
					            (void)sock_close(server, sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1394,7 +1401,7 @@ static int handle_sock(uint32_t key,
 | 
				
			||||||
        goto done;
 | 
					        goto done;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (patty_ax25_sock_write(sock, sock->buf, len) < 0) {
 | 
					    if (patty_ax25_sock_write(sock, sock->rx_buf, len) < 0) {
 | 
				
			||||||
        goto error_sock_write;
 | 
					        goto error_sock_write;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										67
									
								
								src/sock.c
									
										
									
									
									
								
							
							
						
						
									
										67
									
								
								src/sock.c
									
										
									
									
									
								
							| 
						 | 
					@ -64,15 +64,18 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(sock, '\0', sizeof(*sock));
 | 
					    memset(sock, '\0', sizeof(*sock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((sock->buf = malloc(PATTY_AX25_SOCK_BUFSZ)) == NULL) {
 | 
					    if ((sock->rx_buf = malloc(PATTY_AX25_SOCK_BUFSZ)) == NULL) {
 | 
				
			||||||
        goto error_malloc_buf;
 | 
					        goto error_malloc_rx_buf;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((sock->tx_slots = malloc(PATTY_AX25_SOCK_SLOTS_SABM * sizeof(patty_ax25_sock_tx_slot))) == NULL) {
 | 
				
			||||||
 | 
					        goto error_malloc_tx_slots;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (bind_pty(sock) < 0) {
 | 
					    if (bind_pty(sock) < 0) {
 | 
				
			||||||
        goto error_bind_pty;
 | 
					        goto error_bind_pty;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sock->bufsz    = PATTY_AX25_SOCK_BUFSZ;
 | 
					 | 
				
			||||||
    sock->proto    = proto;
 | 
					    sock->proto    = proto;
 | 
				
			||||||
    sock->type     = type;
 | 
					    sock->type     = type;
 | 
				
			||||||
    sock->status   = PATTY_AX25_SOCK_CLOSED;
 | 
					    sock->status   = PATTY_AX25_SOCK_CLOSED;
 | 
				
			||||||
| 
						 | 
					@ -83,9 +86,12 @@ patty_ax25_sock *patty_ax25_sock_new(enum patty_ax25_proto proto,
 | 
				
			||||||
    return sock;
 | 
					    return sock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_bind_pty:
 | 
					error_bind_pty:
 | 
				
			||||||
    free(sock->buf);
 | 
					    free(sock->tx_slots);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_malloc_buf:
 | 
					error_malloc_tx_slots:
 | 
				
			||||||
 | 
					    free(sock->rx_buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_malloc_rx_buf:
 | 
				
			||||||
    free(sock);
 | 
					    free(sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_malloc_sock:
 | 
					error_malloc_sock:
 | 
				
			||||||
| 
						 | 
					@ -114,10 +120,39 @@ void patty_ax25_sock_destroy(patty_ax25_sock *sock) {
 | 
				
			||||||
        close(sock->fd);
 | 
					        close(sock->fd);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    free(sock->buf);
 | 
					    free(sock->rx_buf);
 | 
				
			||||||
 | 
					    free(sock->tx_slots);
 | 
				
			||||||
    free(sock);
 | 
					    free(sock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int patty_ax25_sock_mode_set(patty_ax25_sock *sock,
 | 
				
			||||||
 | 
					                             enum patty_ax25_sock_mode mode) {
 | 
				
			||||||
 | 
					    size_t slots = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sock->mode == mode) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (mode) {
 | 
				
			||||||
 | 
					        case PATTY_AX25_SOCK_SABM:  slots = PATTY_AX25_SOCK_SLOTS_SABM;  break;
 | 
				
			||||||
 | 
					        case PATTY_AX25_SOCK_SABME: slots = PATTY_AX25_SOCK_SLOTS_SABME; break;
 | 
				
			||||||
 | 
					        case PATTY_AX25_SOCK_DM: goto done;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((sock->tx_slots = realloc(sock->tx_slots,
 | 
				
			||||||
 | 
					                                  slots * sizeof(patty_ax25_sock_tx_slot))) == NULL) {
 | 
				
			||||||
 | 
					        goto error_malloc_tx_slots;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
					    sock->mode = mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_malloc_tx_slots:
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *patty_ax25_sock_pty(patty_ax25_sock *sock) {
 | 
					char *patty_ax25_sock_pty(patty_ax25_sock *sock) {
 | 
				
			||||||
    return sock->path;
 | 
					    return sock->path;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -154,9 +189,10 @@ void patty_ax25_sock_seq_recv_incr(patty_ax25_sock *sock) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static size_t addr_copy_to_tx_buf(patty_ax25_sock *sock,
 | 
					static size_t addr_copy_to_buf(void *dest,
 | 
				
			||||||
 | 
					                               patty_ax25_sock *sock,
 | 
				
			||||||
                               enum patty_ax25_frame_cr cr) {
 | 
					                               enum patty_ax25_frame_cr cr) {
 | 
				
			||||||
    uint8_t *buf = sock->iface->tx_buf;
 | 
					    uint8_t *buf = (uint8_t *)dest;
 | 
				
			||||||
    size_t offset = 0;
 | 
					    size_t offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t flags_remote = 0x00,
 | 
					    uint8_t flags_remote = 0x00,
 | 
				
			||||||
| 
						 | 
					@ -190,7 +226,7 @@ static inline int toobig(patty_ax25_sock *sock,
 | 
				
			||||||
                                               PATTY_AX25_FRAME_NORMAL,
 | 
					                                               PATTY_AX25_FRAME_NORMAL,
 | 
				
			||||||
                                 sock->hops,
 | 
					                                 sock->hops,
 | 
				
			||||||
                                 control,
 | 
					                                 control,
 | 
				
			||||||
                                 infolen) > sock->iface->tx_bufsz? 1: 0;
 | 
					                                 infolen) > PATTY_AX25_SOCK_BUFSZ? 1: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
 | 
					ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
 | 
				
			||||||
| 
						 | 
					@ -199,13 +235,13 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
 | 
				
			||||||
                             void *info,
 | 
					                             void *info,
 | 
				
			||||||
                             size_t infolen) {
 | 
					                             size_t infolen) {
 | 
				
			||||||
    size_t offset;
 | 
					    size_t offset;
 | 
				
			||||||
    uint8_t *buf = (uint8_t *)sock->iface->tx_buf;
 | 
					    uint8_t *buf = sock->tx_slots[sock->seq_send].buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (toobig(sock, control, infolen)) {
 | 
					    if (toobig(sock, control, infolen)) {
 | 
				
			||||||
        goto error_toobig;
 | 
					        goto error_toobig;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    offset = addr_copy_to_tx_buf(sock, cr);
 | 
					    offset = addr_copy_to_buf(buf, sock, cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (sock->mode == PATTY_AX25_SOCK_SABME) {
 | 
					    if (sock->mode == PATTY_AX25_SOCK_SABME) {
 | 
				
			||||||
        buf[offset++] = (control & 0xff00) >> 8;
 | 
					        buf[offset++] = (control & 0xff00) >> 8;
 | 
				
			||||||
| 
						 | 
					@ -221,12 +257,21 @@ ssize_t patty_ax25_sock_send(patty_ax25_sock *sock,
 | 
				
			||||||
        offset += infolen;
 | 
					        offset += infolen;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sock->tx_slots[sock->seq_send].len = offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return patty_ax25_if_send(sock->iface, buf, offset);
 | 
					    return patty_ax25_if_send(sock->iface, buf, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_toobig:
 | 
					error_toobig:
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t patty_ax25_sock_resend(patty_ax25_sock *sock,
 | 
				
			||||||
 | 
					                               unsigned int seq) {
 | 
				
			||||||
 | 
					    patty_ax25_sock_tx_slot *slot = &sock->tx_slots[seq];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return patty_ax25_if_send(sock->iface, slot->buf, slot->len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint16_t control_i(patty_ax25_sock *sock, int flag) {
 | 
					static uint16_t control_i(patty_ax25_sock *sock, int flag) {
 | 
				
			||||||
    switch (sock->mode) {
 | 
					    switch (sock->mode) {
 | 
				
			||||||
        case PATTY_AX25_SOCK_SABM:
 | 
					        case PATTY_AX25_SOCK_SABM:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue