Exemple #1
0
// Thread which will handle dequeing and re-enqueing based on the status
// and the flags for all ports in the output buffer
void *output_monitor_routine(void *arg) {
    packet_t in_pkt ;
    ip_address_t address ;
    int dest_port=0 ;
    int loop_count= 0 ;
    element_to_queue * element ;

    while(!die) {

        // Only care dequing if there are elements.
        if((output_buffer->size > 0)) {
            // This will indeed dequeue the packet, but we may
            // have to put it back if the port isn't ready.

            queue_lock(output_buffer) ;
            dequeue(output_buffer,&in_pkt) ;
            queue_unlock(output_buffer) ;

            // Fetch the IP & lookup destination port
            ip_address_copy(&(in_pkt.address),&address);
            dest_port = cam_lookup_address(&address) ;
            if((dest_port != -1) && (dest_port < 4)) {
                // Wait for the lock
                port_lock(&(out_port[dest_port])) ;
                // If the flag is busy from the last write, then
                // we have to put the packet back in the queue and just
                // have to wait until we get to it again.
                if(out_port[dest_port].flag) {
                    element = calloc(1,sizeof(element_to_queue)) ;
                    packet_copy(&in_pkt,&(element->packet));

                    queue_lock(output_buffer) ;
                    enqueue(element,output_buffer) ;
                    queue_unlock(output_buffer) ;

                    port_unlock(&(out_port[dest_port])) ;
                    continue ;
                }
                // Port ready to be written , so go ahead and write.
                packet_copy(&in_pkt,&(out_port[dest_port].packet));
                out_port[dest_port].flag = TRUE ;
                port_unlock(&(out_port[dest_port])) ;
            }
        }
        // Make sure it tried to at least deque 5 elements, before we
        // make it sleep.
        if(loop_count > LOOP_COUNT) {
            loop_count = 0 ;
            sleep() ;
        } else
            loop_count++ ;
    }
}
Exemple #2
0
// send state packet, xor packet if applicable
int network_state_send( void )
{
#ifdef __BLACKBERRY__
#else
	if (!SDLNet_UDP_Send(socket, 0, packet_state_out[0]))
	{
		printf("SDLNet_UDP_Send: %s\n", SDL_GetError());
		return -1;
	}

	// send xor of last network_delay packets
	if (network_delay > 1 && (last_state_out_sync + 1) % network_delay == 0 && packet_state_out[network_delay - 1] != NULL)
	{
		packet_copy(packet_temp, packet_state_out[0]);
		SDLNet_Write16(PACKET_STATE_XOR, &packet_temp->data[0]);
		for (int i = 1; i < network_delay; i++)
			for (int j = 4; j < packet_temp->len; j++)
				packet_temp->data[j] ^= packet_state_out[i]->data[j];

		if (!SDLNet_UDP_Send(socket, 0, packet_temp))
		{
			printf("SDLNet_UDP_Send: %s\n", SDL_GetError());
			return -1;
		}
	}

	packets_shift_down(packet_state_out, NET_PACKET_QUEUE);

	last_state_out_sync++;
#endif
	return 0;
}
Exemple #3
0
// send packet and place it in queue to be acknowledged
bool network_send( int len )
{
#ifdef __BLACKBERRY__
	return true;
#else
	bool temp = network_send_no_ack(len);

	Uint16 i = last_out_sync - queue_out_sync;
	if (i < NET_PACKET_QUEUE)
	{
		packet_out[i] = SDLNet_AllocPacket(NET_PACKET_SIZE);
		packet_copy(packet_out[i], packet_out_temp);
	} else {
		// connection is probably bad now
		fprintf(stderr, "warning: outbound packet queue overflow\n");
		return false;
	}

	last_out_sync++;

	if (network_is_sync())
		last_out_tick = SDL_GetTicks();

	return temp;
#endif
}
Exemple #4
0
int mysql_driver_rewrite_command(packet * in, packet * out,
                                 const char *db_name)
{
    if (command_is_client_auth) {
        int db_name_offset = 36 + strlen(in->bytes + 36) + 2;
        out->size = out->allocated = db_name_offset + strlen(db_name) + 1;
        out->bytes = malloc(out->size);
        if (!out->bytes) {
            out->size = out->allocated = 0;
            return 0;
        }
        bcopy(in->bytes, out->bytes, db_name_offset);
        bcopy(db_name, out->bytes + db_name_offset, strlen(db_name) + 1);
        edit_packet_length(out);
    } else {
        packet *p = packet_copy(in);
        if (!p) {
            return 0;
        }
        out->bytes = p->bytes;
        out->allocated = p->allocated;
        out->size = p->size;
        free(p);
    }

    return 1;
}
Exemple #5
0
void *switch_thread_routine(void *arg)
{
    BOOL recv_flag=FALSE ;
    packet_t in_pkt ;
    ip_address_t address ;
    int dest_port=0 ;
    int i= 0 ;
    element_to_queue * element ;

    while(!die) {
        // Lock all 4 ports first ...
        // This is a better way to do this, since this thread may get
        // preempted and switched back to the input port writer which
        // might override the existing messages.
        for(i=0 ; i < NUM_PORTS ; i++) {
            port_lock(&(in_port[i])) ;
        }

        // Then try to unlock and check if packets are available.
        // We are sure to have saved all elements in the queue once
        // we've unlocked them
        for(i=0 ; i < NUM_PORTS ; i++) {
            if(in_port[i].flag == TRUE) {
                packet_copy(&(in_port[i].packet),&in_pkt);
                in_port[i].flag = FALSE ;
            } else {
                port_unlock(&(in_port[i])) ;
                continue ;
            }
            element = calloc(1,sizeof(element_to_queue)) ;
            packet_copy(&in_pkt,&(element->packet));

            queue_lock(output_buffer) ;
            enqueue(element,output_buffer) ;
            queue_unlock(output_buffer) ;

            port_unlock(&(in_port[i])) ;
        }

        // pause for a a little while and then check again
        sleep() ;
    }
    printf("All packets sent.. Exiting !\n") ;
}
Exemple #6
0
packet *mysql_driver_reduce_replies(packet_set * replies)
{
    lo(LOG_DEBUG, "mysql_driver_reduce_replies: hack hack hack");
    packet *p;
    for (delegate_id i = 0; i < delegate_states_count; ++i) {
        p = packet_set_get(replies, i);
        if (p && p->size) {
            break;
        }
    }
    return packet_copy(p);
}
Exemple #7
0
static void process_eapol(struct network *n,
						  struct client *c,
						  const unsigned char *p,
						  const int len,
						  struct ieee80211_frame *wh,
						  const int totlen)
{
	int num, i;

	num = eapol_handshake_step(p, len);
	if (num == 0) return;

	/* reset... should use time, too.  XXX conservative - check retry */
	if (c->c_wpa == 0 || num <= c->c_wpa)
	{
		for (i = 0; i < 4; i++) c->c_handshake[i].p_len = 0;

		c->c_wpa_got = 0;
	}

	c->c_wpa = num;

	switch (num)
	{
		case 1:
			c->c_wpa_got |= 1;
			break;

		case 2:
			c->c_wpa_got |= 2;
			c->c_wpa_got |= 4;
			break;

		case 3:
			if (memcmp(&p[17], ZERO, 32) != 0) c->c_wpa_got |= 1;

			c->c_wpa_got |= 4;
			break;

		case 4:
			if (memcmp(&p[17], ZERO, 32) != 0) c->c_wpa_got |= 2;

			c->c_wpa_got |= 4;
			break;

		default:
			abort();
	}

	packet_copy(&c->c_handshake[num - 1], wh, totlen);

	if (c->c_wpa_got == 7) n->n_handshake = c;
}
Exemple #8
0
// Given a header to the start of the queue , store the packet in the
// reference.
void dequeue(buf_queue * buffer,packet_t * packet) {
    element_to_queue * ptr_to_remove ;
    if(buffer->head == NULL) {
        return ;
    } else {
        ptr_to_remove = buffer->head ;
        packet_copy(&(buffer->head->packet),packet);
        buffer->head = buffer->head->next ;
        if(buffer->head == NULL) {
            buffer->tail == NULL ;
        }
        buffer->size-- ;
    }
    free(ptr_to_remove) ;
}
Exemple #9
0
// receive state packet, wait until received
bool network_state_update( void )
{
#ifdef __BLACKBERRY__
	return false;
#else
	if (network_state_is_reset())
	{
		return 0;
	} else {
		packets_shift_up(packet_state_in, NET_PACKET_QUEUE);

		packets_shift_up(packet_state_in_xor, NET_PACKET_QUEUE);

		last_state_in_sync++;

		// current xor packet index
		int x = network_delay - (last_state_in_sync - 1) % network_delay - 1;

		// loop until needed packet is available
		while (!packet_state_in[0])
		{
			// xor the packet from thin air, if possible
			if (packet_state_in_xor[x] && SDLNet_Read16(&packet_state_in_xor[x]->data[0]) == PACKET_STATE_XOR)
			{
				// check for all other required packets
				bool okay = true;
				for (int i = 1; i <= x; i++)
				{
					if (packet_state_in[i] == NULL)
					{
						okay = false;
						break;
					}
				}
				if (okay)
				{
					packet_state_in[0] = SDLNet_AllocPacket(NET_PACKET_SIZE);
					packet_copy(packet_state_in[0], packet_state_in_xor[x]);
					for (int i = 1; i <= x; i++)
						for (int j = 4; j < packet_state_in[0]->len; j++)
							packet_state_in[0]->data[j] ^= packet_state_in[i]->data[j];
					break;
				}
			}

			static Uint32 resend_tick = 0;
			if (SDL_GetTicks() - last_state_in_tick > NET_RESEND && SDL_GetTicks() - resend_tick > NET_RESEND)
			{
				SDLNet_Write16(PACKET_STATE_RESEND,    &packet_out_temp->data[0]);
				SDLNet_Write16(last_state_in_sync - 1, &packet_out_temp->data[2]);
				network_send_no_ack(4);  // PACKET_RESEND

				resend_tick = SDL_GetTicks();
			}

			if (network_check() == 0)
				SDL_Delay(1);
		}

		if (network_delay > 1)
		{
			// process the current in packet against the xor queue
			if (packet_state_in_xor[x] == NULL)
			{
				packet_state_in_xor[x] = SDLNet_AllocPacket(NET_PACKET_SIZE);
				packet_copy(packet_state_in_xor[x], packet_state_in[0]);
				packet_state_in_xor[x]->status = 0;
			} else {
				for (int j = 4; j < packet_state_in_xor[x]->len; j++)
					packet_state_in_xor[x]->data[j] ^= packet_state_in[0]->data[j];
			}
		}

		last_state_in_tick = SDL_GetTicks();
	}

	return 1;
#endif
}
Exemple #10
0
// poll for new packets received, check that connection is alive, resend queued packets if necessary
int network_check( void )
{
#ifdef __BLACKBERRY__
#else
	if (!net_initialized)
		return -1;

	if (connected)
	{
		// timeout
		if (!network_is_alive())
		{
			if (!quit)
				network_tyrian_halt(2, false);
		}

		// keep-alive
		static Uint32 keep_alive_tick = 0;
		if (SDL_GetTicks() - keep_alive_tick > NET_KEEP_ALIVE)
		{
			network_prepare(PACKET_KEEP_ALIVE);
			network_send_no_ack(4);

			keep_alive_tick = SDL_GetTicks();
		}
	}

	// retry
	if (packet_out[0] && SDL_GetTicks() - last_out_tick > NET_RETRY)
	{
		if (!SDLNet_UDP_Send(socket, 0, packet_out[0]))
		{
			printf("SDLNet_UDP_Send: %s\n", SDL_GetError());
			return -1;
		}

		last_out_tick = SDL_GetTicks();
	}

	switch (SDLNet_UDP_Recv(socket, packet_temp))
	{
		case -1:
			printf("SDLNet_UDP_Recv: %s\n", SDL_GetError());
			return -1;
			break;
		case 0:
			break;
		default:
			if (packet_temp->channel == 0 && packet_temp->len >= 4)
			{
				switch (SDLNet_Read16(&packet_temp->data[0]))
				{
					case PACKET_ACKNOWLEDGE:
						if ((Uint16)(SDLNet_Read16(&packet_temp->data[2]) - last_ack_sync) < NET_PACKET_QUEUE)
						{
							last_ack_sync = SDLNet_Read16(&packet_temp->data[2]);
						}

						{
							Uint16 i = SDLNet_Read16(&packet_temp->data[2]) - queue_out_sync;
							if (i < NET_PACKET_QUEUE)
							{
								if (packet_out[i])
								{
									SDLNet_FreePacket(packet_out[i]);
									packet_out[i] = NULL;
								}
							}
						}

						// remove acknowledged packets from queue
						while (packet_out[0] == NULL && (Uint16)(last_ack_sync - queue_out_sync) < NET_PACKET_QUEUE)
						{
							packets_shift_up(packet_out, NET_PACKET_QUEUE);

							queue_out_sync++;
						}

						last_in_tick = SDL_GetTicks();
						break;

					case PACKET_CONNECT:
						queue_in_sync = SDLNet_Read16(&packet_temp->data[2]);

						for (int i = 0; i < NET_PACKET_QUEUE; i++)
						{
							if (packet_in[i])
							{
								SDLNet_FreePacket(packet_in[i]);
								packet_in[i] = NULL;
							}
						}

					case PACKET_DETAILS:
					case PACKET_WAITING:
					case PACKET_BUSY:
					case PACKET_GAME_QUIT:
					case PACKET_GAME_PAUSE:
					case PACKET_GAME_MENU:
						{
							Uint16 i = SDLNet_Read16(&packet_temp->data[2]) - queue_in_sync;
							if (i < NET_PACKET_QUEUE)
							{
								if (packet_in[i] == NULL)
									packet_in[i] = SDLNet_AllocPacket(NET_PACKET_SIZE);
								packet_copy(packet_in[i], packet_temp);
							} else {
								// inbound packet queue overflow/underflow
								// under normal circumstances, this is okay
							}
						}

						network_acknowledge(SDLNet_Read16(&packet_temp->data[2]));

					case PACKET_KEEP_ALIVE:
						last_in_tick = SDL_GetTicks();
						break;

					case PACKET_QUIT:
						if (!quit)
						{
							network_prepare(PACKET_QUIT);
							network_send(4);  // PACKET_QUIT
						}

						network_acknowledge(SDLNet_Read16(&packet_temp->data[2]));

						if (!quit)
							network_tyrian_halt(1, true);
						break;

					case PACKET_STATE:
						// place packet in queue if within limits
						{
							Uint16 i = SDLNet_Read16(&packet_temp->data[2]) - last_state_in_sync + 1;
							if (i < NET_PACKET_QUEUE)
							{
								if (packet_state_in[i] == NULL)
									packet_state_in[i] = SDLNet_AllocPacket(NET_PACKET_SIZE);
								packet_copy(packet_state_in[i], packet_temp);
							}
						}
						break;

					case PACKET_STATE_XOR:
						// place packet in queue if within limits
						{
							Uint16 i = SDLNet_Read16(&packet_temp->data[2]) - last_state_in_sync + 1;
							if (i < NET_PACKET_QUEUE)
							{
								if (packet_state_in_xor[i] == NULL)
								{
									packet_state_in_xor[i] = SDLNet_AllocPacket(NET_PACKET_SIZE);
									packet_copy(packet_state_in_xor[i], packet_temp);
								} else if (SDLNet_Read16(&packet_state_in_xor[i]->data[0]) != PACKET_STATE_XOR) {
									for (int j = 4; j < packet_state_in_xor[i]->len; j++)
										packet_state_in_xor[i]->data[j] ^= packet_temp->data[j];
									SDLNet_Write16(PACKET_STATE_XOR, &packet_state_in_xor[i]->data[0]);
								}
							}
						}
						break;

					case PACKET_STATE_RESEND:
						// resend requested state packet if still available
						{
							Uint16 i = last_state_out_sync - SDLNet_Read16(&packet_temp->data[2]);
							if (i > 0 && i < NET_PACKET_QUEUE)
							{
								if (packet_state_out[i])
								{
									if (!SDLNet_UDP_Send(socket, 0, packet_state_out[i]))
									{
										printf("SDLNet_UDP_Send: %s\n", SDL_GetError());
										return -1;
									}
								}
							}
						}
						break;

					default:
						fprintf(stderr, "warning: bad packet %d received\n", SDLNet_Read16(&packet_temp->data[0]));
						return 0;
						break;
				}

				return 1;
			}
			break;
	}
#endif
	return 0;
}
Exemple #11
0
void mysql_driver_reply(delegate_id id, packet * p)
{
    /* have to handle being called unnecessarily */
    if (delegate_states[id].expect_replies == REP_NONE) {
        return;
    }

    /* short-circuit for error packets */
    if ((unsigned char)(p->bytes[4]) == 0xff) {
        char *error = malloc(p->size - 7 + 1);
        if (error) {
            strncpy(error, p->bytes + 7, p->size - 7);
            error[p->size - 7] = 0;
            lo(LOG_INFO, "mysql_driver_reply(%hu): ERROR: %s", id, error);
            free(error);
        }

        delegate_states[id].error = 1;
        delegate_states[id].expect_replies = REP_NONE;
        delegate_states[id].expecting_rows = 0;
        error_packet = packet_copy(p);  /* XX: hacky, will probably need fix */
        return;
    }

    switch (delegate_states[id].expect_replies) {
    case REP_GREETING:
        waiting_for_client_auth = 1;
        lo(LOG_DEBUG, "mysql_driver_reply(%hu): REP_GREETING -> REP_NONE",
           id);
        delegate_states[id].expect_replies = REP_NONE;
        break;
    case REP_SIMPLE:
        if (p->bytes[4] == 0) {
            lo(LOG_DEBUG, "mysql_driver_reply(%hu): REP_SIMPLE -> REP_NONE",
               id);
            delegate_states[id].expect_replies = REP_NONE;
        } else {
            lo(LOG_DEBUG,
               "mysql_driver_reply(%hu): REP_SIMPLE -> REP_TABLE_FIELDS", id);
            delegate_states[id].expect_replies = REP_TABLE_FIELDS;
        }
        break;
    case REP_TABLE_FIELDS:
        if ((unsigned char)(p->bytes[4]) == 0xfe) {
            if (delegate_states[id].expecting_rows) {
                lo(LOG_DEBUG,
                   "mysql_driver_reply(%hu): REP_TABLE_FIELDS "
                   "-> REP_TABLE_ROWS", id);
                delegate_states[id].expect_replies = REP_TABLE_ROWS;
            } else {
                lo(LOG_DEBUG,
                   "mysql_driver_reply(%hu): REP_TABLE_FIELDS -> REP_NONE",
                   id);
                delegate_states[id].expect_replies = REP_NONE;
            }
        } else {
            lo(LOG_DEBUG, "mysql_driver_reply(%hu): field", id);
        }
        break;
    case REP_TABLE_ROWS:
        if ((unsigned char)(p->bytes[4]) == 0xfe) {
            lo(LOG_DEBUG,
               "mysql_driver_reply(%hu): REP_TABLE_ROWS -> REP_NONE", id);
            delegate_states[id].expect_replies = REP_NONE;
        } else {
            lo(LOG_DEBUG, "mysql_driver_reply(%hu): row", id);
        }
        break;
    case REP_NONE:
        lo(LOG_ERROR, "mysql_driver_reply(%hu): I wasn't expecting"
           "any replies!", id);
        break;
    };
}
Exemple #12
0
packet *mysql_driver_error_packet(void)
{
    return packet_copy(error_packet);
}