|
@@ -254,12 +254,10 @@ NetconConnection *NetconEthernetTap::getConnectionByPCB(struct tcp_pcb *pcb)
|
|
|
|
|
|
NetconConnection *NetconEthernetTap::getConnectionByThisFD(int fd)
|
|
|
{
|
|
|
- //fprintf(stderr, " getConnectionByThisFD\n");
|
|
|
for(size_t i=0; i<clients.size(); i++) {
|
|
|
for(size_t j=0; j<clients[i]->connections.size(); j++) {
|
|
|
- if(_phy.getDescriptor(clients[i]->connections[j]->sock) == fd) {
|
|
|
+ if(_phy.getDescriptor(clients[i]->connections[j]->sock) == fd)
|
|
|
return clients[i]->connections[j];
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
return NULL;
|
|
@@ -268,9 +266,8 @@ NetconConnection *NetconEthernetTap::getConnectionByThisFD(int fd)
|
|
|
NetconClient *NetconEthernetTap::getClientByPCB(struct tcp_pcb *pcb)
|
|
|
{
|
|
|
for(size_t i=0; i<clients.size(); i++) {
|
|
|
- if(clients[i]->containsPCB(pcb)) {
|
|
|
+ if(clients[i]->containsPCB(pcb))
|
|
|
return clients[i];
|
|
|
- }
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
@@ -282,16 +279,30 @@ void NetconEthernetTap::closeAllClients()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Closes a NetconConnection and associated LWIP PCB strcuture.
|
|
|
+ */
|
|
|
void NetconEthernetTap::closeConnection(NetconConnection *conn)
|
|
|
{
|
|
|
NetconClient *client = conn->owner;
|
|
|
+ lwipstack->tcp_arg(conn->pcb, NULL);
|
|
|
+ lwipstack->tcp_sent(conn->pcb, NULL);
|
|
|
+ lwipstack->tcp_recv(conn->pcb, NULL);
|
|
|
+ lwipstack->tcp_err(conn->pcb, NULL);
|
|
|
+ lwipstack->tcp_poll(conn->pcb, NULL, 0);
|
|
|
+ lwipstack->tcp_close(conn->pcb);
|
|
|
_phy.close(conn->sock);
|
|
|
lwipstack->tcp_close(conn->pcb);
|
|
|
client->removeConnection(conn->sock);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Closes a NetconClient and all associated NetconConnections (rpc, data, and unmapped)
|
|
|
+ */
|
|
|
void NetconEthernetTap::closeClient(NetconClient *client)
|
|
|
{
|
|
|
+ closeConnection(client->rpc);
|
|
|
+ closeConnection(client->unmapped_conn);
|
|
|
for(size_t i=0; i<client->connections.size(); i++)
|
|
|
{
|
|
|
close(_phy.getDescriptor(client->connections[i]->sock));
|
|
@@ -301,10 +312,6 @@ void NetconEthernetTap::closeClient(NetconClient *client)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*------------------------------------------------------------------------------
|
|
|
------------------------- low-level Interface functions -------------------------
|
|
|
-------------------------------------------------------------------------------*/
|
|
|
-
|
|
|
#define ZT_LWIP_TCP_TIMER_INTERVAL 10
|
|
|
|
|
|
void NetconEthernetTap::threadMain()
|
|
@@ -425,7 +432,6 @@ void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr)
|
|
|
*/
|
|
|
void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len)
|
|
|
{
|
|
|
- fprintf(stderr, "phyOnUnixData(): rpc = %d\n", _phy.getDescriptor(sock));
|
|
|
unsigned char *buf = (unsigned char*)data;
|
|
|
NetconClient *client = (NetconClient*)*uptr;
|
|
|
|
|
@@ -475,7 +481,9 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
|
|
|
void NetconEthernetTap::phyOnUnixWritable(PhySocket *sock,void **uptr)
|
|
|
{
|
|
|
}
|
|
|
-
|
|
|
+/*
|
|
|
+ * Send a return value to the client for an RPC
|
|
|
+ */
|
|
|
int NetconEthernetTap::send_return_value(NetconClient *client, int retval)
|
|
|
{
|
|
|
char retmsg[4];
|
|
@@ -483,7 +491,6 @@ int NetconEthernetTap::send_return_value(NetconClient *client, int retval)
|
|
|
retmsg[0]=RPC_RETVAL;
|
|
|
memcpy(&retmsg[1], &retval, sizeof(retval));
|
|
|
int n = write(_phy.getDescriptor(client->rpc->sock), &retmsg, sizeof(retmsg));
|
|
|
-
|
|
|
if(n > 0) {
|
|
|
// signal that we've satisfied this requirement
|
|
|
client->waiting_for_retval = false;
|
|
@@ -501,6 +508,11 @@ int NetconEthernetTap::send_return_value(NetconClient *client, int retval)
|
|
|
|
|
|
/*
|
|
|
* Callback from LWIP to do whatever work we might need to do.
|
|
|
+ *
|
|
|
+ * @param associated service state object
|
|
|
+ * @param PCB we're polling on
|
|
|
+ * @return ERR_OK if everything is ok, -1 otherwise
|
|
|
+ *
|
|
|
*/
|
|
|
err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb)
|
|
|
{
|
|
@@ -523,6 +535,12 @@ err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb)
|
|
|
* is then required to tell the service what new file descriptor it has allocated
|
|
|
* for this connection. After the mapping is complete, the accepted socket can be
|
|
|
* used.
|
|
|
+ *
|
|
|
+ * @param associated service state object
|
|
|
+ * @param newly allocated PCB
|
|
|
+ * @param error code
|
|
|
+ * @return ERR_OK if everything is ok, -1 otherwise
|
|
|
+ *
|
|
|
*/
|
|
|
err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|
|
{
|
|
@@ -575,6 +593,13 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|
|
*
|
|
|
* Data is in the form of a linked list of struct pbufs, it is then recombined and
|
|
|
* send to the client over the associated unix socket.
|
|
|
+ *
|
|
|
+ * @param associated service state object
|
|
|
+ * @param allocated PCB
|
|
|
+ * @param chain of pbufs
|
|
|
+ * @param error code
|
|
|
+ * @return ERR_OK if everything is ok, -1 otherwise
|
|
|
+ *
|
|
|
*/
|
|
|
err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
|
|
|
{
|
|
@@ -591,8 +616,8 @@ err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf
|
|
|
}
|
|
|
if(p == NULL) {
|
|
|
if(c) {
|
|
|
- //fprintf(stderr, "nc_recved(): closing connection (p==NULL)\n");
|
|
|
- nc_close(tpcb);
|
|
|
+ fprintf(stderr, "nc_recved(): closing connection\n");
|
|
|
+ //tap->_phy.lwipstack->tcp_close(tpcb);
|
|
|
tap->_phy.close(c->sock);
|
|
|
tap->closeConnection(c);
|
|
|
}
|
|
@@ -627,6 +652,10 @@ err_t NetconEthernetTap::nc_recved(void *arg, struct tcp_pcb *tpcb, struct pbuf
|
|
|
*
|
|
|
* Since the PCB related to this error might no longer exist, only its perviously
|
|
|
* associated (arg) is provided to us.
|
|
|
+ *
|
|
|
+ * @param associated service state object
|
|
|
+ * @param error code
|
|
|
+ *
|
|
|
*/
|
|
|
void NetconEthernetTap::nc_err(void *arg, err_t err)
|
|
|
{
|
|
@@ -642,44 +671,32 @@ void NetconEthernetTap::nc_err(void *arg, err_t err)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Callback from LWIP when this PCB has been closed
|
|
|
- */
|
|
|
-void NetconEthernetTap::nc_close(struct tcp_pcb* tpcb)
|
|
|
-{
|
|
|
- fprintf(stderr, "nc_close\n");
|
|
|
- //closeConnection(getConnectionByPCB(tpcb));
|
|
|
- /*
|
|
|
- lwipstack->tcp_arg(tpcb, NULL);
|
|
|
- lwipstack->tcp_sent(tpcb, NULL);
|
|
|
- lwipstack->tcp_recv(tpcb, NULL);
|
|
|
- lwipstack->tcp_err(tpcb, NULL);
|
|
|
- lwipstack->tcp_poll(tpcb, NULL, 0);
|
|
|
- lwipstack->tcp_close(tpcb);
|
|
|
- */
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Callback from LWIP
|
|
|
- */
|
|
|
-err_t NetconEthernetTap::nc_send(struct tcp_pcb *tpcb)
|
|
|
-{
|
|
|
- fprintf(stderr, "nc_send\n");
|
|
|
- return ERR_OK;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Callback from LWIP
|
|
|
+ *
|
|
|
+ * This could be used to track the amount of data sent by a connection.
|
|
|
+ *
|
|
|
+ * @param associated service state object
|
|
|
+ * @param relevant PCB
|
|
|
+ * @param length of data sent
|
|
|
+ * @return ERR_OK if everything is ok, -1 otherwise
|
|
|
+ *
|
|
|
*/
|
|
|
err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len)
|
|
|
{
|
|
|
- fprintf(stderr, "nc_sent\n");
|
|
|
+ //fprintf(stderr, "nc_sent\n");
|
|
|
return len;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Callback from LWIP which sends a return value to the client to signal that
|
|
|
* a connection was established for this PCB
|
|
|
+ *
|
|
|
+ * @param associated service state object
|
|
|
+ * @param relevant PCB
|
|
|
+ * @param error code
|
|
|
+ * @return ERR_OK if everything is ok, -1 otherwise
|
|
|
+ *
|
|
|
*/
|
|
|
err_t NetconEthernetTap::nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
|
|
|
{
|
|
@@ -702,49 +719,44 @@ err_t NetconEthernetTap::nc_connected(void *arg, struct tcp_pcb *tpcb, err_t err
|
|
|
|
|
|
/*
|
|
|
* Handles an RPC to bind an LWIP PCB to a given address and port
|
|
|
+ *
|
|
|
+ * @param Client that is making the RPC
|
|
|
+ * @param structure containing the data and parameters for this client's RPC
|
|
|
+ *
|
|
|
*/
|
|
|
void NetconEthernetTap::handle_bind(NetconClient *client, struct bind_st *bind_rpc)
|
|
|
{
|
|
|
- // FIXME: Is this hack still needed?
|
|
|
struct sockaddr_in *connaddr;
|
|
|
connaddr = (struct sockaddr_in *) &bind_rpc->addr;
|
|
|
int conn_port = lwipstack->ntohs(connaddr->sin_port);
|
|
|
ip_addr_t conn_addr;
|
|
|
conn_addr.addr = *((u32_t *)_ips[0].rawIpData());
|
|
|
-
|
|
|
- /*
|
|
|
- int ip = connaddr->sin_addr.s_addr;
|
|
|
- unsigned char bytes[4];
|
|
|
- bytes[0] = ip & 0xFF;
|
|
|
- bytes[1] = (ip >> 8) & 0xFF;
|
|
|
- bytes[2] = (ip >> 16) & 0xFF;
|
|
|
- bytes[3] = (ip >> 24) & 0xFF;
|
|
|
- fprintf(stderr, "binding to: %d.%d.%d.%d\n", bytes[0], bytes[1], bytes[2], bytes[3]);
|
|
|
- fprintf(stderr, "PORT = %d\n", conn_port);
|
|
|
- */
|
|
|
-
|
|
|
NetconConnection *c = client->getConnectionByTheirFD(bind_rpc->sockfd);
|
|
|
if(c) {
|
|
|
if(c->pcb->state == CLOSED){
|
|
|
int err = lwipstack->tcp_bind(c->pcb, &conn_addr, conn_port);
|
|
|
if(err != ERR_OK) {
|
|
|
- fprintf(stderr, "error while binding to addr/port\n");
|
|
|
+ int ip = connaddr->sin_addr.s_addr;
|
|
|
+ unsigned char d[4];
|
|
|
+ d[0] = ip & 0xFF;
|
|
|
+ d[1] = (ip >> 8) & 0xFF;
|
|
|
+ d[2] = (ip >> 16) & 0xFF;
|
|
|
+ d[3] = (ip >> 24) & 0xFF;
|
|
|
+ fprintf(stderr, "handle_bind(): error binding to %d.%d.%d.%d : %d\n", d[0],d[1],d[2],d[3], conn_port);
|
|
|
}
|
|
|
- else {
|
|
|
- fprintf(stderr, "bind successful\n");
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- fprintf(stderr, "PCB not in CLOSED state. Ignoring BIND request.\n");
|
|
|
+ //else fprintf(stderr, "bind successful\n");
|
|
|
}
|
|
|
+ else fprintf(stderr, "handle_bind(): PCB not in CLOSED state. Ignoring BIND request.\n");
|
|
|
}
|
|
|
- else {
|
|
|
- fprintf(stderr, "can't locate connection for PCB\n");
|
|
|
- }
|
|
|
+ else fprintf(stderr, "handle_bind(): can't locate connection for PCB\n");
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Handles an RPC to put an LWIP PCB into LISTEN mode
|
|
|
+ *
|
|
|
+ * @param Client that is making the RPC
|
|
|
+ * @param structure containing the data and parameters for this client's RPC
|
|
|
+ *
|
|
|
*/
|
|
|
void NetconEthernetTap::handle_listen(NetconClient *client, struct listen_st *listen_rpc)
|
|
|
{
|
|
@@ -775,6 +787,10 @@ void NetconEthernetTap::handle_listen(NetconClient *client, struct listen_st *li
|
|
|
/**
|
|
|
* Handles a return value (client's perceived fd) and completes a mapping
|
|
|
* so that we know what connection an RPC call should be associated with.
|
|
|
+ *
|
|
|
+ * @param Client that is making the RPC
|
|
|
+ * @param structure containing the data and parameters for this client's RPC
|
|
|
+ *
|
|
|
*/
|
|
|
void NetconEthernetTap::handle_retval(NetconClient *client, unsigned char* buf)
|
|
|
{
|
|
@@ -792,6 +808,10 @@ void NetconEthernetTap::handle_retval(NetconClient *client, unsigned char* buf)
|
|
|
* for use in the main ZT I/O loop, and one end is sent to the client. The client
|
|
|
* is then required to tell the service what new file descriptor it has allocated
|
|
|
* for this connection. After the mapping is complete, the socket can be used.
|
|
|
+ *
|
|
|
+ * @param Client that is making the RPC
|
|
|
+ * @param structure containing the data and parameters for this client's RPC
|
|
|
+ *
|
|
|
*/
|
|
|
void NetconEthernetTap::handle_socket(NetconClient *client, struct socket_st* socket_rpc)
|
|
|
{
|
|
@@ -815,6 +835,10 @@ void NetconEthernetTap::handle_socket(NetconClient *client, struct socket_st* so
|
|
|
|
|
|
/*
|
|
|
* Handles an RPC to connect to a given address and port
|
|
|
+ *
|
|
|
+ * @param Client that is making the RPC
|
|
|
+ * @param structure containing the data and parameters for this client's RPC
|
|
|
+ *
|
|
|
*/
|
|
|
void NetconEthernetTap::handle_connect(NetconClient *client, struct connect_st* connect_rpc)
|
|
|
{
|
|
@@ -855,9 +879,11 @@ void NetconEthernetTap::handle_connect(NetconClient *client, struct connect_st*
|
|
|
/*
|
|
|
* Writes data pulled from the client's socket buffer to LWIP. This merely sends the
|
|
|
* data to LWIP to be enqueued and eventually sent to the network.
|
|
|
+ * *
|
|
|
+ * @param Client that is making the RPC
|
|
|
+ * @param structure containing the data and parameters for this client's RPC
|
|
|
*
|
|
|
* TODO: Optimize write logic (should we stop using poll?)
|
|
|
- *
|
|
|
*/
|
|
|
void NetconEthernetTap::handle_write(NetconConnection *c)
|
|
|
{
|