/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "kubernetes.h" #include "terminal/terminal.h" #include #include #include #include #include void guac_kubernetes_receive_data(guac_client* client, const char* buffer, size_t length) { guac_kubernetes_client* kubernetes_client = (guac_kubernetes_client*) client->data; /* Strip channel index from beginning of buffer */ int channel = *(buffer++); length--; switch (channel) { /* Write STDOUT / STDERR directly to terminal as output */ case GUAC_KUBERNETES_CHANNEL_STDOUT: case GUAC_KUBERNETES_CHANNEL_STDERR: guac_terminal_write(kubernetes_client->term, buffer, length); break; /* Ignore data on other channels */ default: guac_client_log(client, GUAC_LOG_DEBUG, "Received %i bytes along " "channel %i.", length, channel); } } void guac_kubernetes_send_message(guac_client* client, int channel, const char* data, int length) { guac_kubernetes_client* kubernetes_client = (guac_kubernetes_client*) client->data; pthread_mutex_lock(&(kubernetes_client->outbound_message_lock)); /* Add message to buffer if space is available */ if (kubernetes_client->outbound_messages_waiting < GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES) { /* Calculate storage position of next message */ int index = (kubernetes_client->outbound_messages_top + kubernetes_client->outbound_messages_waiting) % GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES; /* Obtain pointer to message slot at calculated position */ guac_kubernetes_message* message = &(kubernetes_client->outbound_messages[index]); /* Copy details of message into buffer */ message->channel = channel; memcpy(message->data, data, length); message->length = length; /* One more message is now waiting */ kubernetes_client->outbound_messages_waiting++; /* Notify libwebsockets that we need a callback to send pending * messages */ lws_callback_on_writable(kubernetes_client->wsi); lws_cancel_service(kubernetes_client->context); } /* Warn if data has to be dropped */ else guac_client_log(client, GUAC_LOG_WARNING, "Send buffer could not be " "flushed in time to handle additional data. Outbound " "message dropped."); pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock)); } bool guac_kubernetes_write_pending_message(guac_client* client) { bool messages_remain; guac_kubernetes_client* kubernetes_client = (guac_kubernetes_client*) client->data; pthread_mutex_lock(&(kubernetes_client->outbound_message_lock)); /* Send one message from top of buffer */ if (kubernetes_client->outbound_messages_waiting > 0) { /* Obtain pointer to message at top */ int top = kubernetes_client->outbound_messages_top; guac_kubernetes_message* message = &(kubernetes_client->outbound_messages[top]); /* Write message including channel index */ lws_write(kubernetes_client->wsi, ((unsigned char*) message) + LWS_PRE, message->length + 1, LWS_WRITE_BINARY); /* Advance top to next message */ kubernetes_client->outbound_messages_top++; kubernetes_client->outbound_messages_top %= GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES; /* One less message is waiting */ kubernetes_client->outbound_messages_waiting--; } /* Record whether messages remained at time of completion */ messages_remain = (kubernetes_client->outbound_messages_waiting > 0); pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock)); return messages_remain; }