Changeset - f02df2b37b49
[Not reviewed]
default
0 1 0
Nathan Brink (binki) - 15 years ago 2010-08-07 20:19:22
ohnobinki@ohnopublishing.net
Prevent libdistren from thinking it received the same packet multiple times.
1 file changed with 1 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/client/libdistren_request.c
Show inline comments
 
@@ -8,169 +8,170 @@
 
 * the Free Software Foundation, either version 3 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * DistRen is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU Affero General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU Affero General Public License
 
 * along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
#include "common/config.h"
 

	
 
#include "libdistren.h"
 

	
 
#include "common/protocol.h"
 
#include "common/remoteio.h"
 
#include "common/request.h"
 

	
 
#include <string.h>
 

	
 
static void handle_ping(struct remoteio *rem, struct distren_request *req, void *req_data);
 
static void handle_pong(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data);
 
static void handle_version(distren_t distren, struct distren_request *req, void *req_data);
 
static void handle_disconnect(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data);
 

	
 
size_t libdistren_remoteio_read_handle(struct remoteio *rem, void *garbage, void *buf, size_t len, distren_t distren)
 
{
 
  size_t to_return;
 
  size_t last_len;
 
  short err;
 

	
 
  struct distren_request *req;
 
  void *req_data;
 

	
 
  to_return = 0;
 
  while(!distren->done_ad)
 
    {
 
      if(!len)
 
	return to_return;
 

	
 
      putchar(*(char *)buf);
 
      if(*(char *)buf == '\n')
 
	distren->done_ad = 1;
 

	
 
      len --;
 
      to_return ++;
 
      buf ++;
 
    }
 

	
 
  /* hack to get into the loop at all ;-) */
 
  last_len = 1; 
 
  while(last_len)
 
    {
 
      last_len = distren_request_handle(NULL, buf, len, &req, &req_data, &err);
 
      if(err)
 
	{
 
	  remoteio_close(rem);
 
	  return to_return;
 
	}
 
      if(!last_len)
 
	return to_return;
 

	
 
      switch((enum distren_request_type)req->type)
 
	{
 
	case DISTREN_REQUEST_PING:
 
	  handle_ping(rem, req, req_data);
 
	  break;
 

	
 
	case DISTREN_REQUEST_PONG:
 
	  handle_pong(distren, rem, req, req_data);
 
	  break;
 

	
 
	case DISTREN_REQUEST_VERSION:
 
	  handle_version(distren, req, req_data);
 
	  break;
 

	
 
	case DISTREN_REQUEST_DISCONNECT:
 
	  handle_disconnect(distren, rem, req, req_data);
 
	  break;
 

	
 
	default:
 
	  /*
 
	   * we don't implement everything because we don't need to do
 
	   * so. But, we should complain when we get something we
 
	   * don't recognize because... server protocols change
 
	   * ;-). Oh, and when I'm first writing this, this
 
	   * block will be hit a lot ;-).
 
	   */
 
	  fprintf(stderr, "Unrecognized request type: %lu\n", (unsigned long)req->type);
 
	  break;
 
	}
 

	
 
      distren_request_free(req);
 
      buf += last_len;
 
      to_return += last_len;
 
      len -= last_len;
 
    }
 

	
 
  return to_return;
 
}
 

	
 
void libdistren_remoteio_close_handle(void *garbage, distren_t distren)
 
{
 
  distren->rem = NULL;
 
}
 

	
 

	
 
/* handlers */
 

	
 
static void handle_ping(struct remoteio *rem, struct distren_request *req, void *req_data)
 
{
 
  struct distren_request *pong_req;
 
  void *pong_req_data;
 

	
 
  distren_request_poing(&pong_req, &pong_req_data, 0, req_data, req->len);
 
  distren_request_send(rem, pong_req, pong_req_data);
 
  distren_request_free_with_data(pong_req, pong_req_data);
 
}
 

	
 
static void handle_pong(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data)
 
{
 
  const char *auth_test_str = "auth test";
 

	
 
  if(req->len == strlen(auth_test_str)
 
     && !strncmp(req_data, auth_test_str, req->len))
 
    distren->state = DISTREN_STATE_NORMAL;
 
}
 

	
 
static void handle_version(distren_t distren, struct distren_request *req, void *req_data)
 
{
 
  struct distren_request_version version;
 
  int tmp;
 

	
 
  tmp = distren_request_parse_version(req, req_data, &version);
 
  if(tmp)
 
    {
 
      fprintf(stderr, "error: Invalid DISTREN_REQUEST_VERSION, disconnecting from server\n");
 
      /*
 
       * our remoteio_close handler sets distren->rem to NULL, thus we
 
       * don't need to return an error code.
 
       */
 
      remoteio_close(distren->rem);
 
      return;
 
    }
 
  distren->servertype = version.servertype;
 
  distren->state = DISTREN_STATE_AUTH;
 

	
 
  fprintf(stderr, "info: connected to a server running %s\n", version.package_string);
 
  if(version.servertype & DISTREN_SERVERTYPE_CLIENT)
 
    fprintf(stderr, "\tis a client\n");
 
  if(version.servertype & DISTREN_SERVERTYPE_SUBMIT)
 
    fprintf(stderr, "\taccepts frame submissions\n");
 
  if(version.servertype & DISTREN_SERVERTYPE_RENDER)
 
    fprintf(stderr, "\trenders frames\n");
 
  if(version.servertype & DISTREN_SERVERTYPE_DISTRIBUTE)
 
    fprintf(stderr, "\thandles file distribution\n");
 
}
 

	
 
static void handle_disconnect(distren_t distren, struct remoteio *rem, struct distren_request *req, void *req_data)
 
{
 
  size_t tmp;
 

	
 
  fputs("warning: The server has disconnected us because ``", stderr);
 
  tmp = fwrite(req_data, 1, req->len, stderr);
 
  fputs("''\n", stderr);
 

	
 
  remoteio_close(distren->rem);
 
}
0 comments (0 inline, 0 general)