Skip to content

Instantly share code, notes, and snippets.

@ca0s
Created September 18, 2017 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ca0s/1ddd7b0834a0842038b2b8fcf588bd60 to your computer and use it in GitHub Desktop.
Save ca0s/1ddd7b0834a0842038b2b8fcf588bd60 to your computer and use it in GitHub Desktop.
yadifa simplified functions
static void*
server_rw_udp_receiver(int fd, message_data *mesg)
{
ssize_t n;
mesg->addr_len = sizeof(socketaddress);
n = read(fd, mesg->buffer, MIN(NETWORK_BUFFER_SIZE, sizeof(mesg->buffer)));
if(n >= DNS_HEADER_LENGTH)
{
// now the trick: either direct queue, either delayed queue
mesg->received = n;
}
else if(n >= 0)
{
}
else // n < 0
{
/*
* errno is not a variable but a macro
*/
int err = errno;
if(err != EINTR)
{
/*
* EAGAIN
* Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1)
*/
if(err != EAGAIN)
{
if(err != EBADF)
{
}
// else we are shutting down
}
// else retry
}
// else retry
}
return NULL;
}
static void*
server_rw_udp_sender(int fd, message_data *mesg)
{
if(FAIL(fuzzy_server_rw_udp_sender_process_message(fd, mesg)))
{
return NULL;
}
return NULL;
}
static ya_result
fuzzy_server_rw_udp_sender_process_message(int fd, message_data *mesg)
{
ya_result return_code;
zdb *database = g_config->database;
switch(MESSAGE_OP(mesg->buffer))
{
case OPCODE_QUERY:
{
if(ISOK(return_code = message_process_query(mesg)))
{
switch(mesg->qclass)
{
case CLASS_IN:
{
switch(mesg->qtype)
{
default:
{
#if HAS_RRL_SUPPORT
ya_result rrl = database_query_with_rrl(database, mesg);
switch(rrl)
{
case RRL_SLIP:
{
break;
}
case RRL_DROP:
{
return SUCCESS;
}
case RRL_PROCEED_DROP:
{
break;
}
}
#else
database_query(database, mesg);
#endif
break;
}
case TYPE_IXFR: // reply with a truncate
{
MESSAGE_FLAGS_OR(mesg->buffer, QR_BITS|TC_BITS, 0); /** @todo 20160106 edf -- IXFR UDP */
SET_U32_AT(mesg->buffer[4], 0);
SET_U32_AT(mesg->buffer[8], 0);
mesg->send_length = DNS_HEADER_LENGTH;
break;
}
case TYPE_AXFR:
case TYPE_OPT:
{
message_make_error(mesg, FP_INCORR_PROTO);
break;
}
} // switch query type
break;
} // query class IN
case CLASS_CH:
{
class_ch_process(mesg); // thread-safe
break;
} // query class CH
default:
{
message_make_error(mesg, FP_NOT_SUPP_CLASS);
break;
}
} // query class
} // if message process succeeded
else // an error occurred : no query to be done at all
{
/*
* If not FE, or if we answer FE
*
* ... && (MESSAGE_QR(mesg->buffer) == 0 ??? and if there the query number is > 0 ???
*/
if( (return_code != INVALID_MESSAGE) && ((mesg->status != RCODE_FORMERR) || ((g_config->server_flags & SERVER_FL_ANSWER_FORMERR) != 0)))
{
if(!MESSAGEP_HAS_TSIG(mesg))
{
message_transform_to_error(mesg);
}
}
else
{
return SUCCESS;
}
}
break;
} // case query
case OPCODE_NOTIFY:
{
if(ISOK(return_code = message_process(mesg)))
{
switch(mesg->qclass)
{
case CLASS_IN:
{
ya_result return_value;
bool answer = MESSAGE_QR(mesg->buffer);
return_value = 1; //notify_process(mesg); // thread-safe
if(FAIL(return_value))
{
if(answer)
{
return SUCCESS;
}
if(!MESSAGEP_HAS_TSIG(mesg))
{
message_transform_to_error(mesg);
}
break;
}
else
{
if(answer)
{
return SUCCESS;
}
}
break;
} // notify class IN
default:
{
/// @todo 20140521 edf -- verify unsupported class error handling
/*
FP_CLASS_NOTFOUND
*/
message_make_error(mesg, FP_NOT_SUPP_CLASS);
break;
}
} // notify class
} // if message process succeeded
else // an error occurred : no query to be done at all
else // an error occurred : no query to be done at all
{
/*
* If not FE, or if we answer FE
*
* ... && (MESSAGE_QR(mesg->buffer) == 0 ??? and if there the query number is > 0 ???
*/
if( (return_code != INVALID_MESSAGE) && ((mesg->status != RCODE_FORMERR) || ((g_config->server_flags & SERVER_FL_ANSWER_FORMERR) != 0)))
{
if(!MESSAGEP_HAS_TSIG(mesg))
{
message_transform_to_error(mesg);
}
}
else
{
return SUCCESS;
}
}
break;
} // case notify
case OPCODE_UPDATE:
{
if(ISOK(return_code = message_process(mesg)))
{
switch(mesg->qclass)
{
case CLASS_IN:
{
#if HAS_DYNUPDATE_SUPPORT
/**
* @note It's the responsibility of the called function (or one of its callees) to ensure
* this does not take much time and thus to trigger a background task with the
* scheduler if needed.
*/
// mesg->sockfd = fd;
// server_rw_process_udp_update(mesg);
return SUCCESS; // NOT break;
#else
message_make_error(mesg, FP_FEATURE_DISABLED);
break;
#endif
} // update class IN
default:
{
/// @todo 20140521 edf -- verify unsupported class error handling
/*
FP_CLASS_NOTFOUND
*/
message_make_error(mesg, FP_NOT_SUPP_CLASS);
break;
}
} // update class
} // if message process succeeded
else // an error occurred : no query to be done at all
{
/*
* If not FE, or if we answer FE
*
* ... && (MESSAGE_QR(mesg->buffer) == 0 ??? and if there the query number is > 0 ???
*/
if( (return_code != INVALID_MESSAGE) && ((mesg->status != RCODE_FORMERR) || ((g_config->server_flags & SERVER_FL_ANSWER_FORMERR) != 0)))
{
if(!MESSAGEP_HAS_TSIG(mesg))
{
message_transform_to_error(mesg);
}
}
else
{
return SUCCESS;
}
}
break;
} // case update
default:
{
return_code = message_process_query(mesg);
mesg->status = RCODE_NOTIMP;
if( (mesg->status != RCODE_FORMERR) || ((g_config->server_flags & SERVER_FL_ANSWER_FORMERR) != 0))
{
if(!MESSAGEP_HAS_TSIG(mesg))
{
message_transform_to_error(mesg);
}
}
else
{
return SUCCESS;
}
}
}
/* no need to send replies while fuzzing
while(sendto(fd, mesg->buffer, mesg->send_length, 0, (struct sockaddr*)&mesg->other.sa, mesg->addr_len) < 0)
{
int error_code = errno;
if(error_code != EINTR)
{
return error_code;
}
}
*/
return SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment