Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions src/proxy_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,16 @@ static int process_tcp_open_message(struct proxy_conn_handle *pc,
*/
static int send_tcp_close(struct proxy_conn_handle *pc);

/*!
* @brief Send a ::PROXY_MSG_TYPE_TCP_STATUS message to the client
*
* @param[in,out] pc Target proxy client connection instance
* @param[in] status Status to report to the client
*
* @returns 0 on success, negative ERRNO value on failure
*/
static int send_tcp_status(struct proxy_conn_handle *pc, uint32_t status);

static void forwarder_control(struct worker_handle *wh)
{
struct proxy_conn_handle *pc = wh->func_ctx;
Expand Down Expand Up @@ -706,8 +716,6 @@ static int process_tcp_open_message(struct proxy_conn_handle *pc,
const struct proxy_msg *msg)
{
struct proxy_conn_priv *priv = pc->priv;
uint8_t status_buf[sizeof(struct proxy_msg) + 4] = { 0 };
struct proxy_msg *status_msg = (struct proxy_msg *)status_buf;
const uint8_t *addr_sep = (const uint8_t *)&msg->address;
char addr[16] = "";
int ret;
Expand All @@ -725,6 +733,14 @@ static int process_tcp_open_message(struct proxy_conn_handle *pc,
return -EINVAL;
}

/* Disconnect any existing connection */
conn_close(&priv->conn_tcp);
ret = worker_wait_idle(&priv->worker_tcp);
if (ret < 0) {
send_tcp_status(pc, ret);
return ret;
}

/* Attempt to connect */
ret = conn_connect(&priv->conn_tcp, (const char *)addr, "5200");
if (ret < 0) {
Expand All @@ -738,44 +754,54 @@ static int process_tcp_open_message(struct proxy_conn_handle *pc,
conn_close(&priv->conn_tcp);
}

status_msg->type = PROXY_MSG_TYPE_TCP_STATUS;
status_msg->size = 4;
return send_tcp_status(pc, ret);
}

/* Unless we can figure out what the client is expecting here, the
* best we can do is a "non-zero" value to indicate failure.
*/
memcpy(status_buf + sizeof(*status_msg), &ret, 4);
static int send_tcp_close(struct proxy_conn_handle *pc)
{
struct proxy_conn_priv *priv = pc->priv;
struct proxy_msg message = { 0 };
int ret;

message.type = PROXY_MSG_TYPE_TCP_CLOSE;
message.size = 0;

proxy_log(pc->ph, LOG_LEVEL_DEBUG,
"Sending TCP_STATUS message (%d) to client '%s'\n",
ret, priv->callsign);
"Sending TCP_CLOSE message to client '%s'\n", priv->callsign);

mutex_lock(&priv->mutex_client_send);

ret = conn_send(priv->conn_client, status_buf,
sizeof(*status_msg) + status_msg->size);
ret = conn_send(priv->conn_client, (uint8_t *)&message,
sizeof(struct proxy_msg));

mutex_unlock(&priv->mutex_client_send);

return ret;
}

static int send_tcp_close(struct proxy_conn_handle *pc)
static int send_tcp_status(struct proxy_conn_handle *pc, uint32_t status)
{
struct proxy_conn_priv *priv = pc->priv;
struct proxy_msg message = { 0 };
uint8_t status_buf[sizeof(struct proxy_msg) + 4] = { 0 };
struct proxy_msg *status_msg = (struct proxy_msg *)status_buf;
int ret;

message.type = PROXY_MSG_TYPE_TCP_CLOSE;
message.size = 0;
status_msg->type = PROXY_MSG_TYPE_TCP_STATUS;
status_msg->size = 4;

/* Unless we can figure out what the client is expecting here, the
* best we can do is a "non-zero" value to indicate failure.
*/
memcpy(status_buf + sizeof(*status_msg), &status, 4);

proxy_log(pc->ph, LOG_LEVEL_DEBUG,
"Sending TCP_CLOSE message to client '%s'\n", priv->callsign);
"Sending TCP_STATUS message (%d) to client '%s'\n",
status, priv->callsign);

mutex_lock(&priv->mutex_client_send);

ret = conn_send(priv->conn_client, (uint8_t *)&message,
sizeof(struct proxy_msg));
ret = conn_send(priv->conn_client, status_buf,
sizeof(struct proxy_msg) + status_msg->size);

mutex_unlock(&priv->mutex_client_send);

Expand Down
Loading