mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-14 07:11:32 +00:00
Made the temporary buffer part of the TCP senddata() API, to ease the
transition away from uIP. Prepared ipv4.c for transition away from uIP.
This commit is contained in:
parent
3c8aafa209
commit
8637834031
@ -66,6 +66,8 @@ struct tcp_operations {
|
||||
* Transmit data
|
||||
*
|
||||
* @v conn TCP connection
|
||||
* @v buf Temporary data buffer
|
||||
* @v len Length of temporary data buffer
|
||||
*
|
||||
* The application should transmit whatever it currently wants
|
||||
* to send using tcp_send(). If retransmissions are required,
|
||||
@ -73,8 +75,16 @@ struct tcp_operations {
|
||||
* regenerate the data. The easiest way to implement this is
|
||||
* to ensure that senddata() never changes the application's
|
||||
* state.
|
||||
*
|
||||
* The application may use the temporary data buffer to
|
||||
* construct the data to be sent. Note that merely filling
|
||||
* the buffer will do nothing; the application must call
|
||||
* tcp_send() in order to actually transmit the data. Use of
|
||||
* the buffer is not compulsory; the application may call
|
||||
* tcp_send() on any block of data.
|
||||
*/
|
||||
void ( * senddata ) ( struct tcp_connection *conn );
|
||||
void ( * senddata ) ( struct tcp_connection *conn, void *buf,
|
||||
size_t len );
|
||||
};
|
||||
|
||||
/**
|
||||
@ -88,8 +98,6 @@ struct tcp_connection {
|
||||
struct tcp_operations *tcp_op;
|
||||
};
|
||||
|
||||
extern void *tcp_buffer;
|
||||
extern size_t tcp_buflen;
|
||||
extern void tcp_connect ( struct tcp_connection *conn );
|
||||
extern void tcp_send ( struct tcp_connection *conn, const void *data,
|
||||
size_t len );
|
||||
|
@ -176,8 +176,9 @@ int ipv4_uip_tx ( struct pk_buff *pkb ) {
|
||||
* This handles IP packets by handing them off to the uIP protocol
|
||||
* stack.
|
||||
*/
|
||||
static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
const void *ll_source __unused ) {
|
||||
static int ipv4_uip_rx ( struct pk_buff *pkb,
|
||||
struct net_device *netdev __unused,
|
||||
const void *ll_source __unused ) {
|
||||
|
||||
/* Transfer to uIP buffer. Horrendously space-inefficient,
|
||||
* but will do as a proof-of-concept for now.
|
||||
@ -250,7 +251,11 @@ struct net_protocol ipv4_protocol = {
|
||||
.name = "IP",
|
||||
.net_proto = htons ( ETH_P_IP ),
|
||||
.net_addr_len = sizeof ( struct in_addr ),
|
||||
#if USE_UIP
|
||||
.rx = ipv4_uip_rx,
|
||||
#else
|
||||
.rx = ipv4_rx,
|
||||
#endif
|
||||
.ntoa = ipv4_ntoa,
|
||||
};
|
||||
|
||||
|
@ -40,11 +40,10 @@
|
||||
*
|
||||
* @code
|
||||
*
|
||||
* static void my_senddata ( struct tcp_connection *conn ) {
|
||||
* int len;
|
||||
*
|
||||
* len = snprintf ( tcp_buffer, tcp_buflen, "FETCH %s\r\n", filename );
|
||||
* tcp_send ( conn, tcp_buffer + already_sent, len - already_sent );
|
||||
* static void my_senddata ( struct tcp_connection *conn, void *buf,
|
||||
* size_t len ) {
|
||||
* len = snprintf ( buf, len, "FETCH %s\r\n", filename );
|
||||
* tcp_send ( conn, buf + already_sent, len - already_sent );
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
@ -53,13 +52,12 @@
|
||||
* variably-sized data.
|
||||
*
|
||||
* Note that you cannot use this simple mechanism if you want to be
|
||||
* able to construct single data blocks of more than #tcp_buflen
|
||||
* bytes.
|
||||
* able to construct single data blocks of more than #len bytes.
|
||||
*/
|
||||
void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN );
|
||||
static void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN );
|
||||
|
||||
/** Size of #tcp_buffer */
|
||||
size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN );
|
||||
static size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN );
|
||||
|
||||
/**
|
||||
* Open a TCP connection
|
||||
@ -148,7 +146,7 @@ void uip_tcp_appcall ( void ) {
|
||||
op->newdata ( conn, ( void * ) uip_appdata, uip_len );
|
||||
if ( ( uip_rexmit() || uip_newdata() || uip_acked() ||
|
||||
uip_connected() || uip_poll() ) && op->senddata )
|
||||
op->senddata ( conn );
|
||||
op->senddata ( conn, tcp_buffer, tcp_buflen );
|
||||
}
|
||||
|
||||
/* Present here to allow everything to link. Will go into separate
|
||||
|
@ -220,20 +220,21 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
|
||||
* Construct data to send on FTP control channel
|
||||
*
|
||||
* @v conn TCP connection
|
||||
* @v buf Temporary data buffer
|
||||
* @v len Length of temporary data buffer
|
||||
*/
|
||||
static void ftp_senddata ( struct tcp_connection *conn ) {
|
||||
static void ftp_senddata ( struct tcp_connection *conn,
|
||||
void *buf, size_t len ) {
|
||||
struct ftp_request *ftp = tcp_to_ftp ( conn );
|
||||
const struct ftp_string *string;
|
||||
size_t len;
|
||||
|
||||
/* Send the as-yet-unACKed portion of the string for the
|
||||
* current state.
|
||||
*/
|
||||
string = &ftp_strings[ftp->state];
|
||||
len = snprintf ( tcp_buffer, tcp_buflen, string->format,
|
||||
len = snprintf ( buf, len, string->format,
|
||||
ftp_string_data ( ftp, string->data_offset ) );
|
||||
tcp_send ( conn, tcp_buffer + ftp->already_sent,
|
||||
len - ftp->already_sent );
|
||||
tcp_send ( conn, buf + ftp->already_sent, len - ftp->already_sent );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -222,24 +222,27 @@ static void iscsi_data_out_done ( struct iscsi_session *iscsi ) {
|
||||
* Send iSCSI data-out data segment
|
||||
*
|
||||
* @v iscsi iSCSI session
|
||||
* @v buf Temporary data buffer
|
||||
* @v len Length of temporary data buffer
|
||||
*/
|
||||
static void iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
|
||||
static void iscsi_tx_data_out ( struct iscsi_session *iscsi,
|
||||
void *buf, size_t len ) {
|
||||
struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
|
||||
unsigned long offset;
|
||||
unsigned long len;
|
||||
unsigned long remaining;
|
||||
|
||||
offset = ( iscsi->transfer_offset + ntohl ( data_out->offset ) +
|
||||
iscsi->tx_offset );
|
||||
len = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset );
|
||||
remaining = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset);
|
||||
assert ( iscsi->command != NULL );
|
||||
assert ( iscsi->command->data_out != NULL );
|
||||
assert ( ( offset + len ) <= iscsi->command->data_out_len );
|
||||
|
||||
if ( len > tcp_buflen )
|
||||
len = tcp_buflen;
|
||||
copy_from_user ( tcp_buffer, iscsi->command->data_out, offset, len );
|
||||
if ( remaining < len )
|
||||
len = remaining;
|
||||
copy_from_user ( buf, iscsi->command->data_out, offset, len );
|
||||
|
||||
tcp_send ( &iscsi->tcp, tcp_buffer, len );
|
||||
tcp_send ( &iscsi->tcp, buf, len );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -336,15 +339,15 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
|
||||
* Transmit data segment of an iSCSI login request PDU
|
||||
*
|
||||
* @v iscsi iSCSI session
|
||||
* @v buf Temporary data buffer
|
||||
* @v len Length of temporary data buffer
|
||||
*
|
||||
* For login requests, the data segment consists of the login strings.
|
||||
*/
|
||||
static void iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
|
||||
int len;
|
||||
|
||||
len = iscsi_build_login_request_strings ( iscsi, tcp_buffer,
|
||||
tcp_buflen );
|
||||
tcp_send ( &iscsi->tcp, tcp_buffer + iscsi->tx_offset,
|
||||
static void iscsi_tx_login_request ( struct iscsi_session *iscsi,
|
||||
void *buf, size_t len ) {
|
||||
len = iscsi_build_login_request_strings ( iscsi, buf, len );
|
||||
tcp_send ( &iscsi->tcp, buf + iscsi->tx_offset,
|
||||
len - iscsi->tx_offset );
|
||||
}
|
||||
|
||||
@ -422,19 +425,22 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ) {
|
||||
* Transmit data segment of an iSCSI PDU
|
||||
*
|
||||
* @v iscsi iSCSI session
|
||||
* @v buf Temporary data buffer
|
||||
* @v len Length of temporary data buffer
|
||||
*
|
||||
* Handle transmission of part of a PDU data segment. iscsi::tx_bhs
|
||||
* will be valid when this is called.
|
||||
*/
|
||||
static void iscsi_tx_data ( struct iscsi_session *iscsi ) {
|
||||
static void iscsi_tx_data ( struct iscsi_session *iscsi,
|
||||
void *buf, size_t len ) {
|
||||
struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
|
||||
|
||||
switch ( common->opcode & ISCSI_OPCODE_MASK ) {
|
||||
case ISCSI_OPCODE_DATA_OUT:
|
||||
iscsi_tx_data_out ( iscsi );
|
||||
iscsi_tx_data_out ( iscsi, buf, len );
|
||||
break;
|
||||
case ISCSI_OPCODE_LOGIN_REQUEST:
|
||||
iscsi_tx_login_request ( iscsi );
|
||||
iscsi_tx_login_request ( iscsi, buf, len );
|
||||
break;
|
||||
default:
|
||||
assert ( 0 );
|
||||
@ -524,10 +530,13 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) {
|
||||
* Transmit iSCSI PDU
|
||||
*
|
||||
* @v iscsi iSCSI session
|
||||
* @v buf Temporary data buffer
|
||||
* @v len Length of temporary data buffer
|
||||
*
|
||||
* Constructs data to be sent for the current TX state
|
||||
*/
|
||||
static void iscsi_senddata ( struct tcp_connection *conn ) {
|
||||
static void iscsi_senddata ( struct tcp_connection *conn,
|
||||
void *buf, size_t len ) {
|
||||
struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
|
||||
struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
|
||||
static const char pad[] = { '\0', '\0', '\0' };
|
||||
@ -545,7 +554,7 @@ static void iscsi_senddata ( struct tcp_connection *conn ) {
|
||||
assert ( 0 );
|
||||
break;
|
||||
case ISCSI_TX_DATA:
|
||||
iscsi_tx_data ( iscsi );
|
||||
iscsi_tx_data ( iscsi, buf, len );
|
||||
break;
|
||||
case ISCSI_TX_DATA_PADDING:
|
||||
tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths )
|
||||
|
@ -569,4 +569,6 @@ extern void uip_tcp_appcall ( void );
|
||||
#define UIP_IPADDR2 254
|
||||
#define UIP_IPADDR3 1
|
||||
|
||||
#define USE_UIP 1
|
||||
|
||||
#endif /* __UIPOPT_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user