Browse Source

Moved file system management and random string code to appropriate files.

File system code is now in fs.{h|c}. This includes:

    - spool directory setup
    - metadata file management
    - pcap file creation and writing

Random hex string generation is now in str.h.
pull/245/head
Dylan Mikus 10 years ago
committed by Eric Green
parent
commit
7c53e9f95b
8 changed files with 325 additions and 242 deletions
  1. +1
    -1
      daemon/Makefile
  2. +2
    -133
      daemon/call.c
  3. +214
    -0
      daemon/fs.c
  4. +53
    -0
      daemon/fs.h
  5. +2
    -56
      daemon/main.c
  6. +1
    -52
      daemon/media_socket.c
  7. +45
    -0
      daemon/str.c
  8. +7
    -0
      daemon/str.h

+ 1
- 1
daemon/Makefile View File

@ -69,7 +69,7 @@ endif
SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \
bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \
crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c graphite.c ice.c socket.c \
media_socket.c rtcp_xr.c homer.c
media_socket.c rtcp_xr.c homer.c fs.c
OBJS= $(SRCS:.c=.o)


+ 2
- 133
daemon/call.c View File

@ -37,6 +37,7 @@
#include "ice.h"
#include "rtpengine_config.h"
#include "log_funcs.h"
#include "fs.h"
@ -132,13 +133,6 @@ const char * get_tag_type_text(enum tag_type t) {
static void __monologue_destroy(struct call_monologue *monologue);
static int monologue_destroy(struct call_monologue *ml);
/* Generate a random PCAP filepath to write recorded RTP stream. */
str *setup_recording_file(struct call *call, struct call_monologue *monologue);
/* Generates a random string sandwiched between affixes. */
char *rand_affixed_str(int num_bytes, char *prefix, char *suffix);
/* Generates a hex string representing n random bytes. len(rand_str) = 2*num_bytes + 1 */
char *rand_hex_str(char *rand_str, int num_bytes);
/* called with call->master_lock held in R */
static int call_timer_delete_monologues(struct call *c) {
GList *i;
@ -2234,46 +2228,6 @@ void call_destroy(struct call *c) {
rwlock_unlock_w(&c->master_lock);
}
/**
* Writes metadata to metafile, closes file, and renames it to finished location.
* Returns non-zero for failure.
*/
int meta_file_finish(struct call *call) {
int return_code = 0;
if (call->meta_fp != NULL) {
fprintf(call->meta_fp, "\n%s\n", call->metadata->s);
fclose(call->meta_fp);
// Get the filename (in between its directory and the file extension)
// and move it to the finished file location.
// Rename extension to ".txt".
int fn_len;
char *meta_filename = strrchr(call->meta_filepath->s, '/');
char *meta_ext = NULL;
if (meta_filename == NULL)
meta_filename = call->meta_filepath->s;
else
meta_filename = meta_filename + 1;
// We can always expect a file extension
meta_ext = strrchr(meta_filename, '.');
fn_len = meta_ext - meta_filename;
int prefix_len = 30; // for "/var/spool/rtpengine/metadata/"
int ext_len = 4; // for ".txt"
char new_metapath[prefix_len + fn_len + ext_len + 1];
snprintf(new_metapath, prefix_len+fn_len+1, "/var/spool/rtpengine/metadata/%s", meta_filename);
snprintf(new_metapath + prefix_len+fn_len, ext_len+1, ".txt");
return_code = return_code | rename(call->meta_filepath->s, new_metapath);
}
if (call->meta_filepath != NULL) {
free(call->meta_filepath->s);
free(call->meta_filepath);
}
return return_code;
}
/* XXX move these */
int call_stream_address46(char *o, struct packet_stream *ps, enum stream_address_format format,
@ -2377,20 +2331,7 @@ static struct call *call_create(const str *callid, struct callmaster *m) {
c->dtls_cert = dtls_cert();
c->tos = m->conf.default_tos;
int rand_bytes = 16;
str *meta_filepath = malloc(sizeof(str));
// Initially file extension is ".tmp". When call is over, it changes to ".txt".
char *path_chars = rand_affixed_str(rand_bytes, "/tmp/rtpengine-meta-", ".tmp");
meta_filepath = str_init(meta_filepath, path_chars);
c->meta_filepath = meta_filepath;
FILE *mfp = fopen(meta_filepath->s, "w");
if (mfp == NULL) {
ilog(LOG_ERROR, "Could not open metadata file: %s", meta_filepath->s);
free(c->meta_filepath->s);
free(c->meta_filepath);
c->meta_filepath = NULL;
}
c->meta_fp = mfp;
setup_meta_file(c);
return c;
}
@ -2920,75 +2861,3 @@ const struct transport_protocol *transport_protocol(const str *s) {
out:
return NULL;
}
/**
* Generate a random PCAP filepath to write recorded RTP stream.
*/
str *setup_recording_file(struct call *call, struct call_monologue *monologue) {
str *recording_path = NULL;
if (call->record_call
&& monologue->recording_pd == NULL && monologue->recording_pdumper == NULL) {
int rand_bytes = 16;
recording_path = malloc(sizeof(str));
char *path_chars = rand_affixed_str(rand_bytes, "/var/spool/rtpengine/recordings/", ".pcap");
recording_path = str_init(recording_path, path_chars);
monologue->recording_path = recording_path;
call->recording_pcaps = g_slist_prepend(call->recording_pcaps, g_strdup(path_chars));
/* monologue->recording_file */
monologue->recording_pd = pcap_open_dead(DLT_RAW, 65535);
monologue->recording_pdumper = pcap_dump_open(monologue->recording_pd, recording_path);
} else {
monologue->recording_path = NULL;
monologue->recording_pd = NULL;
monologue->recording_pdumper = NULL;
}
return recording_path;
}
/**
* Generates a random string sandwiched between affixes.
* Will create the char string for you. Don't forget to clean up!
*/
char *rand_affixed_str(int num_bytes, char *prefix, char *suffix) {
int rand_len = num_bytes*2 + 1;
char rand_prefix[rand_len];
int prefix_len = strlen(prefix);
int suffix_len = strlen(suffix);
char *full_path = calloc(rand_len + prefix_len + suffix_len, sizeof(char));
rand_hex_str(rand_prefix, num_bytes);
snprintf(full_path, rand_len+prefix_len, "%s%s", prefix, rand_prefix);
snprintf(full_path + rand_len+prefix_len-1, suffix_len+1, "%s", suffix);
return full_path;
}
/**
* Generates a random hexadecimal string representing n random bytes.
* rand_str length must be 2*num_bytes + 1.
*/
char *rand_hex_str(char *rand_str, int num_bytes) {
char rand_tmp[3];
u_int8_t rand_byte;
int i, n;
// We might convert an int to a hex string shorter than 2 digits.
// This causes those strings to have leading '0' characters.
for (i=0; i<num_bytes*2 + 1; i++) {
rand_str[i] = '0';
}
for (i=0; i<num_bytes; i++) {
// Determine the length of the hex byte string.
// If less than two, offset by 2-len to pad with prefix zeroes.
rand_byte = (u_int8_t)rand();
snprintf(rand_tmp, 3, "%x", rand_byte);
n = strlen(rand_tmp);
snprintf(rand_str + i*2 + (2-n), 3, "%s", rand_tmp);
rand_str[i*2 + 2] = '0';
}
rand_str[num_bytes*2] = '\0';
return rand_str;
}

+ 214
- 0
daemon/fs.c View File

@ -0,0 +1,214 @@
#include "fs.h"
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include "call.h"
int maybe_create_spool_dir(char *dirpath);
/**
* Initialize RTP Engine filesystem settings and structure.
* Check for or create the RTP Engine spool directory.
*/
void fs_init(char *spoolpath) {
// TODO should we change the umask at all?
if (!maybe_create_spool_dir(spoolpath)) {
fprintf(stderr, "Error while setting up spool directory \"%s\".\n", spoolpath);
exit(-1);
}
}
/**
* Sets up the spool directory for RTP Engine.
* If the directory does not exist, return FALSE.
* If the directory exists, but "$dirpath/metadata" or "$dirpath/recordings"
* exist as non-directory files, return FALSE.
* Otherwise, return TRUE.
*
* Create the "metadata" and "recordings" directories if they are not there.
*/
int maybe_create_spool_dir(char *dirpath) {
struct stat info;
int spool_good = TRUE;
if (stat(dirpath, &info) != 0) {
fprintf(stderr, "Spool directory \"%s\" does not exist.\n", dirpath);
spool_good = FALSE;
} else if (!S_ISDIR(info.st_mode)) {
fprintf(stderr, "Spool file exists, but \"%s\" is not a directory.\n", dirpath);
spool_good = FALSE;
} else {
// Spool directory exists. Make sure it has inner directories.
int path_len = strlen(dirpath);
char meta_path[path_len + 10];
char rec_path[path_len + 12];
snprintf(meta_path, path_len + 10, "%s/metadata", dirpath);
snprintf(rec_path, path_len + 12, "%s/recordings", dirpath);
if (stat(meta_path, &info) != 0) {
fprintf(stdout, "Creating metadata directory \"%s\".\n", meta_path);
mkdir(meta_path, 0660);
} else if(!S_ISDIR(info.st_mode)) {
fprintf(stderr, "Metadata file exists, but \"%s\" is not a directory.\n", meta_path);
spool_good = FALSE;
}
if (stat(rec_path, &info) != 0) {
fprintf(stdout, "Creating recordings directory \"%s\".\n", rec_path);
mkdir(rec_path, 0660);
} else if(!S_ISDIR(info.st_mode)) {
fprintf(stderr, "Recordings file exists, but \"%s\" is not a directory.\n", rec_path);
spool_good = FALSE;
}
}
return spool_good;
}
/**
* Create a call metadata file in a temporary location.
* Attaches the filepath and the file pointer to the call struct.
*/
str *setup_meta_file(struct call *call) {
int rand_bytes = 16;
str *meta_filepath = malloc(sizeof(str));
// Initially file extension is ".tmp". When call is over, it changes to ".txt".
char *path_chars = rand_affixed_str(rand_bytes, "/tmp/rtpengine-meta-", ".tmp");
meta_filepath = str_init(meta_filepath, path_chars);
call->meta_filepath = meta_filepath;
FILE *mfp = fopen(meta_filepath->s, "w");
if (mfp == NULL) {
ilog(LOG_ERROR, "Could not open metadata file: %s", meta_filepath->s);
free(call->meta_filepath->s);
free(call->meta_filepath);
call->meta_filepath = NULL;
}
call->meta_fp = mfp;
return meta_filepath;
}
/**
* Writes metadata to metafile, closes file, and renames it to finished location.
* Returns non-zero for failure.
*/
int meta_file_finish(struct call *call) {
int return_code = 0;
if (call->meta_fp != NULL) {
fprintf(call->meta_fp, "\n%s\n", call->metadata->s);
fclose(call->meta_fp);
// Get the filename (in between its directory and the file extension)
// and move it to the finished file location.
// Rename extension to ".txt".
int fn_len;
char *meta_filename = strrchr(call->meta_filepath->s, '/');
char *meta_ext = NULL;
if (meta_filename == NULL)
meta_filename = call->meta_filepath->s;
else
meta_filename = meta_filename + 1;
// We can always expect a file extension
meta_ext = strrchr(meta_filename, '.');
fn_len = meta_ext - meta_filename;
int prefix_len = 30; // for "/var/spool/rtpengine/metadata/"
int ext_len = 4; // for ".txt"
char new_metapath[prefix_len + fn_len + ext_len + 1];
snprintf(new_metapath, prefix_len+fn_len+1, "/var/spool/rtpengine/metadata/%s", meta_filename);
snprintf(new_metapath + prefix_len+fn_len, ext_len+1, ".txt");
return_code = return_code | rename(call->meta_filepath->s, new_metapath);
}
if (call->meta_filepath != NULL) {
free(call->meta_filepath->s);
free(call->meta_filepath);
}
return return_code;
}
/**
* Generate a random PCAP filepath to write recorded RTP stream.
*/
str *setup_recording_file(struct call *call, struct call_monologue *monologue) {
str *recording_path = NULL;
if (call->record_call
&& monologue->recording_pd == NULL && monologue->recording_pdumper == NULL) {
int rand_bytes = 16;
recording_path = malloc(sizeof(str));
char *path_chars = rand_affixed_str(rand_bytes, "/var/spool/rtpengine/recordings/", ".pcap");
recording_path = str_init(recording_path, path_chars);
monologue->recording_path = recording_path;
call->recording_pcaps = g_slist_prepend(call->recording_pcaps, g_strdup(path_chars));
/* monologue->recording_file */
monologue->recording_pd = pcap_open_dead(DLT_RAW, 65535);
monologue->recording_pdumper = pcap_dump_open(monologue->recording_pd, path_chars);
} else {
monologue->recording_path = NULL;
monologue->recording_pd = NULL;
monologue->recording_pdumper = NULL;
}
return recording_path;
}
/**
* Write out a PCAP packet with payload string.
* A fair amount extraneous of packet data is spoofed.
*/
void stream_pcap_dump(pcap_dumper_t *pdumper, str *s) {
// Wrap RTP in fake UDP packet header
// Right now, we spoof it all
u_int16_t udp_len = ((u_int16_t)s->len) + 8;
u_int16_t udp_header[4];
udp_header[0] = htons(5028); // source port
udp_header[1] = htons(50116); // destination port
udp_header[2] = htons(udp_len); // packet length
udp_header[3] = 0; // checksum
// Wrap RTP in fake IP packet header
u_int8_t ip_header[20];
u_int16_t *ip_total_length = (u_int16_t*)(ip_header + 2);
u_int32_t *ip_src_addr = (u_int32_t*)(ip_header + 12);
u_int32_t *ip_dst_addr = (u_int32_t*)(ip_header + 16);
memset(ip_header, 0, 20);
ip_header[0] = 4 << 4; // IP version - 4 bits
ip_header[0] = ip_header[0] | 5; // Internet Header Length (IHL) - 4 bits
ip_header[1] = 0; // DSCP - 6 bits
ip_header[1] = 0; // ECN - 2 bits
*ip_total_length = htons(udp_len + 20); // Total Length (entire packet size) - 2 bytes
ip_header[4] = 0; ip_header[5] = 0 ; // Identification - 2 bytes
ip_header[6] = 0; // Flags - 3 bits
ip_header[7] = 0; // Fragment Offset - 13 bits
ip_header[8] = 64; // TTL - 1 byte
ip_header[9] = 17; // Protocol (defines protocol in data portion) - 1 byte
ip_header[10] = 0; ip_header[11] = 0; // Header Checksum - 2 bytes
*ip_src_addr = htonl(2130706433); // Source IP (set to localhost) - 4 bytes
*ip_dst_addr = htonl(2130706433); // Destination IP (set to localhost) - 4 bytes
// Set up PCAP packet header
struct pcap_pkthdr header;
ZERO(header);
header.ts = g_now;
header.caplen = s->len + 28;
// This must be the same value we use in `pcap_open_dead`
header.len = s->len + 28;
// Copy all the headers and payload into a new string
unsigned char pkt_s[*ip_total_length];
memcpy(pkt_s, ip_header, 20);
memcpy(pkt_s + 20, udp_header, 8);
memcpy(pkt_s + 28, s->s, s->len);
// Write the packet to the PCAP file
// Casting quiets compiler warning.
pcap_dump((unsigned char *)pdumper, &header, (unsigned char *)pkt_s);
}

+ 53
- 0
daemon/fs.h View File

@ -0,0 +1,53 @@
#ifndef __FS_H__
#define __FS_H__
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include "call.h"
/**
* Initialize RTP Engine filesystem settings and structure.
* Check for or create the RTP Engine spool directory.
*/
void fs_init(char *spooldir);
/**
* Create a call metadata file in a temporary location.
* Attaches the filepath and the file pointer to the call struct.
* Returns path to created file.
*
* Metadata file format is (with trailing newline):
*
* /path/to/rec-pcap01.pcap
* /path/to/rec-pcap02.pcap
* ...
* /path/to/rec-pcap0n.pcap
*
* start timestamp (YYYY-MM-DDThh:mm:ss)
* end timestamp (YYYY-MM-DDThh:mm:ss)
*
* metadata
*
*/
str *setup_meta_file(struct call *call);
/**
* Writes metadata to metafile, closes file, and renames it to finished location.
* Returns non-zero for failure.
*/
int meta_file_finish(struct call *call);
/**
* Generate a random PCAP filepath to write recorded RTP stream.
* Returns path to created file.
*/
str *setup_recording_file(struct call *call, struct call_monologue *monologue);
/**
* Write out a PCAP packet with payload string.
* A fair amount extraneous of packet data is spoofed.
*/
void stream_pcap_dump(pcap_dumper_t *pdumper, str *s);
#endif

+ 2
- 56
daemon/main.c View File

@ -11,8 +11,6 @@
#include <stdlib.h>
#include <time.h>
#include <openssl/ssl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "poller.h"
#include "control_tcp.h"
@ -32,6 +30,7 @@
#include "socket.h"
#include "media_socket.h"
#include "homer.h"
#include "fs.h"
@ -520,6 +519,7 @@ static void init_everything() {
socket_init();
log_init();
fs_init("/var/spool/rtpengine");
clock_gettime(CLOCK_REALTIME, &ts);
srandom(ts.tv_sec ^ ts.tv_nsec);
SSL_library_init();
@ -551,13 +551,6 @@ static void create_everything(struct main_context *ctx) {
struct timeval redis_start, redis_stop;
double redis_diff = 0;
// TODO this should be a configurable path
char spoolpath[] = "/var/spool/rtpengine";
if (!maybe_create_spool_dir(spoolpath)) {
fprintf(stderr, "Error while setting up spool directory \"%s\".\n", spoolpath);
exit(-1);
}
if (table < 0)
goto no_kernel;
if (kernel_create_table(table)) {
@ -696,53 +689,6 @@ no_kernel:
}
/**
* Sets up the spool directory for RTP Engine.
* If the directory does not exist, return FALSE.
* If the directory exists, but "$dirpath/metadata" or "$dirpath/recordings"
* exist as non-directory files, return FALSE.
* Otherwise, return TRUE.
*
* Create the "metadata" and "recordings" directories if they are not there.
*/
int maybe_create_spool_dir(char *dirpath) {
struct stat info;
int spool_good = TRUE;
if (stat(dirpath, &info) != 0) {
fprintf(stderr, "Spool directory \"%s\" does not exist.\n", dirpath);
spool_good = FALSE;
} else if (!S_ISDIR(info.st_mode)) {
fprintf(stderr, "Spool file exists, but \"%s\" is not a directory.\n", dirpath);
spool_good = FALSE;
} else {
// Spool directory exists. Make sure it has inner directories.
int path_len = strlen(dirpath);
char meta_path[path_len + 10];
char rec_path[path_len + 12];
snprintf(meta_path, path_len + 10, "%s/metadata", dirpath);
snprintf(rec_path, path_len + 12, "%s/recordings", dirpath);
if (stat(meta_path, &info) != 0) {
fprintf(stdout, "Creating metadata directory \"%s\".\n", meta_path);
mkdir(meta_path, 0700);
} else if(!S_ISDIR(info.st_mode)) {
fprintf(stderr, "Metadata file exists, but \"%s\" is not a directory.\n", meta_path);
spool_good = FALSE;
}
if (stat(rec_path, &info) != 0) {
fprintf(stdout, "Creating recordings directory \"%s\".\n", rec_path);
mkdir(rec_path, 0700);
} else if(!S_ISDIR(info.st_mode)) {
fprintf(stderr, "Recordings file exists, but \"%s\" is not a directory.\n", rec_path);
spool_good = FALSE;
}
}
return spool_good;
}
int main(int argc, char **argv) {
struct main_context ctx;
int idx=0;


+ 1
- 52
daemon/media_socket.c View File

@ -18,6 +18,7 @@
#include "aux.h"
#include "log_funcs.h"
#include "poller.h"
#include "fs.h"
@ -48,8 +49,6 @@ struct streamhandler {
static void determine_handler(struct packet_stream *in, const struct packet_stream *out);
static void stream_pcap_dump(pcap_dumper_t *pdumper, str *s);
static int __k_null(struct rtpengine_srtp *s, struct packet_stream *);
static int __k_srtp_encrypt(struct rtpengine_srtp *s, struct packet_stream *);
static int __k_srtp_decrypt(struct rtpengine_srtp *s, struct packet_stream *);
@ -1369,56 +1368,6 @@ unlock_out:
}
static void stream_pcap_dump(pcap_dumper_t *pdumper, str *s) {
// Wrap RTP in fake UDP packet header
// Right now, we spoof it all
u_int16_t udp_len = ((u_int16_t)s->len) + 8;
u_int16_t udp_header[4];
udp_header[0] = htons(5028); // source port
udp_header[1] = htons(50116); // destination port
udp_header[2] = htons(udp_len); // packet length
udp_header[3] = 0; // checksum
// Wrap RTP in fake IP packet header
u_int8_t ip_header[20];
u_int16_t *ip_total_length = (u_int16_t*)(ip_header + 2);
u_int32_t *ip_src_addr = (u_int32_t*)(ip_header + 12);
u_int32_t *ip_dst_addr = (u_int32_t*)(ip_header + 16);
memset(ip_header, 0, 20);
ip_header[0] = 4 << 4; // IP version - 4 bits
ip_header[0] = ip_header[0] | 5; // Internet Header Length (IHL) - 4 bits
ip_header[1] = 0; // DSCP - 6 bits
ip_header[1] = 0; // ECN - 2 bits
*ip_total_length = htons(udp_len + 20); // Total Length (entire packet size) - 2 bytes
ip_header[4] = 0; ip_header[5] = 0 ; // Identification - 2 bytes
ip_header[6] = 0; // Flags - 3 bits
ip_header[7] = 0; // Fragment Offset - 13 bits
ip_header[8] = 64; // TTL - 1 byte
ip_header[9] = 17; // Protocol (defines protocol in data portion) - 1 byte
ip_header[10] = 0; ip_header[11] = 0; // Header Checksum - 2 bytes
*ip_src_addr = htonl(2130706433); // Source IP (set to localhost) - 4 bytes
*ip_dst_addr = htonl(2130706433); // Destination IP (set to localhost) - 4 bytes
// Set up PCAP packet header
struct pcap_pkthdr header;
ZERO(header);
header.ts = g_now;
header.caplen = s->len + 28;
// This must be the same value we use in `pcap_open_dead`
header.len = s->len + 28;
// Copy all the headers and payload into a new string
unsigned char pkt_s[*ip_total_length];
memcpy(pkt_s, ip_header, 20);
memcpy(pkt_s + 20, udp_header, 8);
memcpy(pkt_s + 28, s->s, s->len);
// Write the packet to the PCAP file
// Casting quiets compiler warning.
pcap_dump((unsigned char *)pdumper, &header, (unsigned char *)pkt_s);
}
static void stream_fd_readable(int fd, void *p, uintptr_t u) {
struct stream_fd *sfd = p;
char buf[RTP_BUFFER_SIZE];


+ 45
- 0
daemon/str.c View File

@ -33,3 +33,48 @@ str *__str_sprintf(const char *fmt, ...) {
void str_slice_free(void *p) {
g_slice_free1(sizeof(str), p);
}
/**
* Generates a random string sandwiched between affixes.
* Will create the char string for you. Don't forget to clean up!
*/
char *rand_affixed_str(int num_bytes, char *prefix, char *suffix) {
int rand_len = num_bytes*2 + 1;
char rand_prefix[rand_len];
int prefix_len = strlen(prefix);
int suffix_len = strlen(suffix);
char *full_path = calloc(rand_len + prefix_len + suffix_len, sizeof(char));
rand_hex_str(rand_prefix, num_bytes);
snprintf(full_path, rand_len+prefix_len, "%s%s", prefix, rand_prefix);
snprintf(full_path + rand_len+prefix_len-1, suffix_len+1, "%s", suffix);
return full_path;
}
/**
* Generates a random hexadecimal string representing n random bytes.
* rand_str length must be 2*num_bytes + 1.
*/
char *rand_hex_str(char *rand_str, int num_bytes) {
char rand_tmp[3];
u_int8_t rand_byte;
int i, n;
// We might convert an int to a hex string shorter than 2 digits.
// This causes those strings to have leading '0' characters.
for (i=0; i<num_bytes*2 + 1; i++) {
rand_str[i] = '0';
}
for (i=0; i<num_bytes; i++) {
// Determine the length of the hex byte string.
// If less than two, offset by 2-len to pad with prefix zeroes.
rand_byte = (u_int8_t)rand();
snprintf(rand_tmp, 3, "%x", rand_byte);
n = strlen(rand_tmp);
snprintf(rand_str + i*2 + (2-n), 3, "%s", rand_tmp);
rand_str[i*2 + 2] = '0';
}
rand_str[num_bytes*2] = '\0';
return rand_str;
}

+ 7
- 0
daemon/str.h View File

@ -292,4 +292,11 @@ INLINE int str_token(str *new_token, str *ori_and_remainder, int sep) {
return 0;
}
/* Generates a random string sandwiched between affixes. */
char *rand_affixed_str(int num_bytes, char *prefix, char *suffix);
/* Generates a hex string representing n random bytes. len(rand_str) = 2*num_bytes + 1 */
char *rand_hex_str(char *rand_str, int num_bytes);
#endif

Loading…
Cancel
Save