Andre Noll [Sat, 21 May 2011 19:06:01 +0000 (21:06 +0200)]
Simplify ogg_post_select().
Currently, in each invocation of post_select(), we allocate a
640K buffer and shrink it afterwards to the actual size of the
decoded data. This is ugly and unnecessary.
This patch changes ogg_post_select() to allocate and fill 32K
buffers until the maximal output size is reached or there is
nothing left to decode.
Andre Noll [Sat, 30 Jul 2011 16:14:25 +0000 (18:14 +0200)]
mp3_afh: Take padding into account when computing frame duration.
Without this fix, the computed duration of a frame can be slightly
larger than its actual duration. If this happens for many frames of
an mp3 file, the chunk size will be slightly too large, which leads
to buffer underruns during streaming.
Andre Noll [Sun, 7 Aug 2011 10:33:03 +0000 (12:33 +0200)]
mp3dec: Handle decode errors gracefully.
Currently decoding damaged mp3 files leads to very audible artefacts
even if only a single frame is corrupt. This patch instructs the mp3
decoder to synchronize the stream on decode errors and to continue the
decode process. Only on fatal errors the input buffer is discarded.
Andre Noll [Thu, 14 Jul 2011 06:17:08 +0000 (08:17 +0200)]
vss: Clean up timeout computations.
By passing the sched struct to vss_compute_timeout() we can get
rid of the static the_timeout struct in vss_compute_timeout(). The
previous patch, which made the timeout helper functions of sched.c
return whether the given barrier is in the past, allows to simplify
the timeout code of vss.c a bit.
The patch also combines the general timeout computations and the
computation for FEC slices into a single function.
Andre Noll [Wed, 13 Jul 2011 19:13:32 +0000 (21:13 +0200)]
sched: Improve sched_request_barrier() and friends.
Make these functions tell its caller whether the given barrier
was in the past. This is useful for vss because for certain
barriers, no other actions should be performed before the barrier
has passed.
Andre Noll [Fri, 5 Aug 2011 10:53:46 +0000 (12:53 +0200)]
gcrypt: Return key size in bytes.
The crypto API requires get_asymmetric_key() to return the size of
the RSA key in bytes on success. The return value is evaluated in
populate_user_list() where keys which are too short to encrypt a
challenge buffer are rejected right away.
However, for ASN.1 keys, the gcrypt implementation returned the number
of *bits* instead. This caused para_server to accept keys which are
in fact not suitable for authentication.
Andre Noll [Sun, 31 Jul 2011 12:40:10 +0000 (14:40 +0200)]
afs: Fix long-standing bug in add command.
Before the add command handler adds a given audio file to the database
it asks the afs process to check whether the file already exists.
The afs process looks for rows in the audio file table with path
and/or hash identical to the given file. If a match is found a
pointer to the matching row is passed from afs to the command handler.
The get_row_pointer_from_result() helper is then called by the command
handler to extract the row pointer from the result returned by afs.
However, this helper incorrectly dereferenced the pointer which caused
the command handler to examine an address rather than the content of
the address to tell whether the file already exists and whether path
or content has changed. This could lead to changed/moved files being
ignored as well as existing files being added again.
This bug was introduced in commit 0a3b9b83, back in 2008.
Andre Noll [Thu, 21 Jul 2011 17:59:46 +0000 (19:59 +0200)]
sched: Optimize the case of zero timeouts.
If a pre_select method calls sched_min_delay() there is no
point in calling the pre_select hooks of the other tasks since
these can not decrease the timeout any further, and adding file
descriptors to the fd sets makes no sense either. So we may
break out early in sched_preselect() in this case.
If the timeout is zero we may even omit the entire select call as
well as the subsequent gettimeofday() since select() will return
immediately anyway. This patch teaches sched_postselect() to do so
which saves at least two system calls (plus locking in case of
para_server) in a rather hot path.
Andre Noll [Thu, 21 Jul 2011 17:39:03 +0000 (19:39 +0200)]
sched: Kill unnecessary check in sched_pre_select().
The only two callers of sched_shutdown() call this function
from post_select context, so we may safely remove the check
whether the pre_select list is empty.
Add a comment to sched_shutdown() which mentions that this
function must be called from post_select.
Andre Noll [Fri, 3 Jun 2011 04:58:45 +0000 (06:58 +0200)]
Don't ship generated *cmdline.[ch] files in tarball.
These files increase the size of the tarball considerably for no real
gain. Gengetopt is available as a package on all major distributions,
so simply require gengetopt.
Andre Noll [Sun, 24 Jul 2011 20:18:42 +0000 (22:18 +0200)]
alsa: Avoid busy loop.
It is possible that snd_pcm_writei() returns zero rather than -EAGAIN
in case nothing was written because the alsa buffer was already full.
Currently we try again, and eventually succeed. However, this is
ugly, burns CPU cycles and might even lead to an endless loop for
misconfigured alsa devices. So simply return from alsa_post_select()
if snd_pcm_writei() returned zero.
Andre Noll [Thu, 9 Jun 2011 22:01:09 +0000 (00:01 +0200)]
client: Do not leak buffer tree node on exit.
Currently we deallocate the buffer tree node of the client
task in case the connect fails and in audiod.c's close_stat_pipe()
but miss to free it for para_client in case of a regular connection
shutdown.
Fix this memory leak by freeing the buffer tree node in
client_close().
Andre Noll [Thu, 3 Feb 2011 16:15:39 +0000 (17:15 +0100)]
Rewrite of the osx writer.
This replaces most of the code taken from mosx-mpg123 and should
make osx_write.c much more readable, shorter and more reliable.
Since coreaudio creates a new thread which periodically calls our
callback function, some kind of coordination between the two threads
of execution is necessary.
This implementation employs a new buffer tree node and a mutex to
serialize access to the data buffers. The parent thread pushes
down all data to the child thread which consumes this data in the
callback function. Both threads grab the new mutex whenever they
access or modify the data buffers.
Andre Noll [Thu, 3 Feb 2011 16:12:53 +0000 (17:12 +0100)]
audiod get_play_time_slot_num(): Avoid possible NULL pointer dereference.
The pointer to the buffer tree node is dereferenced unconditionally
in btr_get_node_start(). This patch makes sure we never pass a NULL
pointer to this function.
Andre Noll [Thu, 9 Jun 2011 15:52:13 +0000 (17:52 +0200)]
Work around some clang warnings.
This fixes a bunch of warnings of the form
command.c:126:2: warning: expression result unused [-Wunused-value]
WRITE_STATUS_ITEM(&b, SI_MTIME, "%s\n", mtime);
when compiling with clang. This warning is bogus, because the underlying call
to para_printf() can only return failure if the max_size_handler fails, but
this handler is never called here because the size of this para_buffer is
unlimited.
Andre Noll [Mon, 4 Jul 2011 23:04:34 +0000 (01:04 +0200)]
gcrypt: Optionally use internal OAEP padding.
libgcrypt supports OAEP padding since version 1.5.0, which has just
been released. Since want the paraslash gcrypt code to work also
for older gcrypt libraries, we check the library version at runtime
and fall back to the internal OAEP padding code if an old library
was detected.
This patch moves much of the rather ugly OAEP padding code into new
new helper decode_rsa() which reduces to a mere memcpy for newer
gcrypt versions. Much of the old code can be removed once all major
distributions ship libgcrypt-1.5.0 or later.
Andre Noll [Sat, 4 Jun 2011 13:26:15 +0000 (15:26 +0200)]
Add alternative crypto implementation.
This fills gcrypt.c (which contained only dummy functions so far)
with contents.
The old openssl-based crypto API uses OAEP padding exclusively, as
this padding method is recommended for new applications which do not
have to care about backwards compatibility. Unfortunately, libcrypt
only supports the older pkcs1 padding method. Since we want older
para_client versions to be compatible with a newer para_server, even
if this para_server was compiled against libgcrypt, we must implement
our own OAEP padding functions. This turned out to be quite simple,
given the good documentation in rfc 3447.
This together with the fact that there is no ASN1 parser in libgcrypt
makes the patch quite large though.
On the other hand, SHA1, random numbers and RC4 were straight-forward
to implement using the primitives provided by libgcrypt.
Andre Noll [Mon, 7 Mar 2011 07:07:37 +0000 (08:07 +0100)]
stream cipher: Allow in-place encryption.
unlike openssl's RC4(), the RC4 implemenation of libgcrypt can encrypt
a buffer in-place. For this the "buf" argument of the various send
and receive functions must not be const.
Andre Noll [Mon, 7 Mar 2011 07:04:23 +0000 (08:04 +0100)]
crypt: Make base64_decode public.
gcrypt.c needs this to decode public rsa keys. Public functions
should always return proper error codes, so change the return
value for errors from -1 to -E_BASE64.
Andre Noll [Sat, 5 Mar 2011 20:53:54 +0000 (21:53 +0100)]
crypt: Move implementation-independent code to separate file.
This introduces crypt_common.c which contains helper functions from
crypt.c which are independent of openssl.
crypt.common.c contains two types of public functions: Frontend
functions are called by users of the crypto API, and these functions
are exported as usual through the crypt.h header file. Backend
functions, on the other hand, are expected to be called only from
the crypto implementation (i.e. from crypt.c or gcrypt.c). These
functions are exported through the new crypt_backend.h header file.
Andre Noll [Sun, 5 Jun 2011 17:14:37 +0000 (19:14 +0200)]
Clear score table on mood reload.
Whenever a blob is added, the mood event handler is called
which may reload the current mood in order to react to the
change being made. However, we missed to clear the score table
first. This is necessary to to re-insert all admissible files.
Currently this fails with
afs_event: table moods, event 8: key already exists in rbtree
Andre Noll [Mon, 6 Jun 2011 06:24:08 +0000 (08:24 +0200)]
alsa: Avoid busy loop at end of file.
During the drain period at the end of input the status of the alsa
buffer tree node is negative, yet we should not request a minimal
scheduler delay until the end of this period.
Andre Noll [Sat, 4 Jun 2011 11:38:02 +0000 (13:38 +0200)]
aft: Do not invalidate status items when closing the audio file table.
Currently aft_close() frees the global variables status_items and
parser_friendly_status_items which are used for the stat comand of
para_server. This function is called on exit and when para_server
receives SIGHUP, the latter may happen while streaming. In this case
clients which connect after the SIGHUP do not see any aft status
items until the audio file changes.
Fix this flaw simply by not freeing the status item buffers until
they are recomputed anyway.
Andre Noll [Tue, 19 Apr 2011 23:28:10 +0000 (01:28 +0200)]
audiod: Document new regular expression syntax.
This changes the man page and the manual. The
usage of regular expressions for receiver, filter
and writers are explained and some examples are
provided.
Andre Noll [Tue, 19 Apr 2011 16:18:45 +0000 (18:18 +0200)]
audiod: Allow regular expressions in receiver config.
The audio format substring of the reciever arg can now be a regular
expression rather than only the name of an audio format. This way
one can easily choose the same receiver for all audio formats by
saying e.g.
receiver ".:udp"
This works because the regex "." matches all audio formats.
Andre Noll [Sun, 29 May 2011 11:53:32 +0000 (13:53 +0200)]
ogg_get_file_info(): Fix off-by-one.
The timing information encoded in the chunk table was not always
sufficient to guarantee no buffer underruns since vorbis frames
are frequently spread over two (or more) ogg pages. This should
fix it.
Andre Noll [Fri, 22 Apr 2011 02:21:48 +0000 (04:21 +0200)]
net.c: Combine host_and_port() and __get_sock_name().
host_and_port() is only called by __get_sock_name().
Both functions are short enough, and merging these
two functions has the additional benefit that we can
always return the same static buffer.
Compiling with -Wwrite-strings previously caused a
warning due to returning either a string literal, or
the static buffer. We now always print into that buffer
and return it.
This also improves the error message which is returned
in the static buffer in case of failures: Previously we
returned "(don't know)" if getname() failed and "(unknown)"
if getnameinfo() failed. This turns it into "(unknown)" in
the former case and "(lookup error)" otherwise.
Andre Noll [Thu, 3 Feb 2011 16:15:27 +0000 (17:15 +0100)]
libao: Avoid segfault on com_cycle.
Executing the cycle command while the ao writer is active can lead to
a segmentation fault because kill_all_decoders() removes the buffer
tree node of the ao writer but leaves its child node alive.
This patch changes kill_all_decoders() to kill the receiver node only
while leaving all other nodes alone, removing the assumption that
the set of filter nodes and writer nodes are the only nodes in the
buffer tree. This assumption used to be true but became false with
the merge of the ao writer which has two buffer tree nodes.
It is enough to kill only the receiver node as all other nodes will
eventually notice that their parent node no longer exists and exit
shortly thereafter.
Andre Noll [Thu, 25 Nov 2010 07:33:20 +0000 (08:33 +0100)]
Add support for ssh-rsa keys.
This allows to use standard ssh keys (that is, keys generated with
ssh-keygen) for the challenge/response authentication method of
paraslash. Only RSA keys without password protection are supported
at the moment.
Since we want that both openssl and ssh keys just work, we introduce
the helper function is_ssh_rsa_key(). It looks at the first few bytes
of the key to decide which type of public key we have. For openssl
keys, we just call openssl's EVP_PKEY_get1_RSA() and be done. Private
keys generated by ssh-keygen do not differ from keys generated by
"openssl rsa" and need no special treatment either.
However, public ssh rsa keys are stored differently, as an uuencoded
byte stream. So this patch adds functions that decode a given buffer
via base64 or uudecode. The two rsa public parameters (modulus and
exponent) are then read from the decoded buffer using BN_bin2bn().
Andre Noll [Tue, 26 Apr 2011 14:33:44 +0000 (16:33 +0200)]
fd: Allow passing NULL to para_munmap().
This patch makes para_munmap succeed with return value 0 if the passed
"start" pointer is NULL. This allows to simplify the code in the
callers a bit, similar to free(NULL).