/* * lwip-arch.c * * Arch-specific semaphores and mailboxes for lwIP running on mini-os * * Tim Deegan , July 2007 */ #include #include #include #include #include #include /* Is called to initialize the sys_arch layer */ void sys_init(void) { } /* Creates and returns a new semaphore. The "count" argument specifies * the initial state of the semaphore. */ sys_sem_t sys_sem_new(u8_t count) { struct semaphore *sem = xmalloc(struct semaphore); sem->count = count; init_waitqueue_head(&sem->wait); return sem; } /* Deallocates a semaphore. */ void sys_sem_free(sys_sem_t sem) { xfree(sem); } /* Signals a semaphore. */ void sys_sem_signal(sys_sem_t sem) { up(sem); } /* Blocks the thread while waiting for the semaphore to be * signaled. If the "timeout" argument is non-zero, the thread should * only be blocked for the specified time (measured in * milliseconds). * * If the timeout argument is non-zero, the return value is the number of * milliseconds spent waiting for the semaphore to be signaled. If the * semaphore wasn't signaled within the specified time, the return value is * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore * (i.e., it was already signaled), the function may return zero. */ u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) { /* Slightly more complicated than the normal minios semaphore: * need to wake on timeout *or* signal */ sys_prot_t prot; s64_t then = NOW(); s64_t deadline; if (timeout == 0) deadline = 0; else deadline = then + MILLISECS(timeout); while(1) { wait_event_deadline(sem->wait, (sem->count > 0), deadline); prot = sys_arch_protect(); /* Atomically check that we can proceed */ if (sem->count > 0 || (deadline && NOW() >= deadline)) break; sys_arch_unprotect(prot); } if (sem->count > 0) { sem->count--; sys_arch_unprotect(prot); return NSEC_TO_MSEC(NOW() - then); } sys_arch_unprotect(prot); return SYS_ARCH_TIMEOUT; } /* Creates an empty mailbox. */ sys_mbox_t sys_mbox_new(int size) { struct mbox *mbox = xmalloc(struct mbox); if (!size) size = 32; else if (size == 1) size = 2; mbox->count = size; mbox->messages = xmalloc_array(void*, size); init_SEMAPHORE(&mbox->read_sem, 0); mbox->reader = 0; init_SEMAPHORE(&mbox->write_sem, size); mbox->writer = 0; return mbox; } /* Deallocates a mailbox. If there are messages still present in the * mailbox when the mailbox is deallocated, it is an indication of a * programming error in lwIP and the developer should be notified. */ void sys_mbox_free(sys_mbox_t mbox) { ASSERT(mbox->reader == mbox->writer); xfree(mbox->messages); xfree(mbox); } /* Posts the "msg" to the mailbox, internal version that actually does the * post. */ static void do_mbox_post(sys_mbox_t mbox, void *msg) { /* The caller got a semaphore token, so we are now allowed to increment * writer, but we still need to prevent concurrency between writers * (interrupt handler vs main) */ sys_prot_t prot = sys_arch_protect(); mbox->messages[mbox->writer] = msg; mbox->writer = (mbox->writer + 1) % mbox->count; ASSERT(mbox->reader != mbox->writer); sys_arch_unprotect(prot); up(&mbox->read_sem); } /* Posts the "msg" to the mailbox. */ void sys_mbox_post(sys_mbox_t mbox, void *msg) { if (mbox == SYS_MBOX_NULL) return; down(&mbox->write_sem); do_mbox_post(mbox, msg); } /* Try to post the "msg" to the mailbox. */ err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) { if (mbox == SYS_MBOX_NULL) return ERR_BUF; if (!trydown(&mbox->write_sem)) return ERR_MEM; do_mbox_post(mbox, msg); return ERR_OK; } /* * Fetch a message from a mailbox. Internal version that actually does the * fetch. */ static void do_mbox_fetch(sys_mbox_t mbox, void **msg) { sys_prot_t prot; /* The caller got a semaphore token, so we are now allowed to increment * reader, but we may still need to prevent concurrency between readers. * FIXME: can there be concurrent readers? */ prot = sys_arch_protect(); ASSERT(mbox->reader != mbox->writer); if (msg != NULL) *msg = mbox->messages[mbox->reader]; mbox->reader = (mbox->reader + 1) % mbox->count; sys_arch_unprotect(prot); up(&mbox->write_sem); } /* Blocks the thread until a message arrives in the mailbox, but does * not block the thread longer than "timeout" milliseconds (similar to * the sys_arch_sem_wait() function). The "msg" argument is a result * parameter that is set by the function (i.e., by doing "*msg = * ptr"). The "msg" parameter maybe NULL to indicate that the message * should be dropped. * * The return values are the same as for the sys_arch_sem_wait() function: * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a * timeout. */ u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) { u32 rv; if (mbox == SYS_MBOX_NULL) return SYS_ARCH_TIMEOUT; rv = sys_arch_sem_wait(&mbox->read_sem, timeout); if ( rv == SYS_ARCH_TIMEOUT ) return rv; do_mbox_fetch(mbox, msg); return 0; } /* This is similar to sys_arch_mbox_fetch, however if a message is not * present in the mailbox, it immediately returns with the code * SYS_MBOX_EMPTY. On success 0 is returned. * * To allow for efficient implementations, this can be defined as a * function-like macro in sys_arch.h instead of a normal function. For * example, a naive implementation could be: * #define sys_arch_mbox_tryfetch(mbox,msg) \ * sys_arch_mbox_fetch(mbox,msg,1) * although this would introduce unnecessary delays. */ u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) { if (mbox == SYS_MBOX_NULL) return SYS_ARCH_TIMEOUT; if (!trydown(&mbox->read_sem)) return SYS_MBOX_EMPTY; do_mbox_fetch(mbox, msg); return 0; } /* Returns a pointer to the per-thread sys_timeouts structure. In lwIP, * each thread has a list of timeouts which is repressented as a linked * list of sys_timeout structures. The sys_timeout
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import, division, print_function

INCLUDES = """
#include <openssl/x509.h>

/*
 * See the comment above Cryptography_STACK_OF_X509 in x509.py
 */
typedef STACK_OF(X509_NAME) Cryptography_STACK_OF_X509_NAME;
typedef STACK_OF(X509_NAME_ENTRY) Cryptography_STACK_OF_X509_NAME_ENTRY;
"""

TYPES = """
typedef ... Cryptography_STACK_OF_X509_NAME_ENTRY;
typedef ... X509_NAME;
typedef ... X509_NAME_ENTRY;
typedef ... Cryptography_STACK_OF_X509_NAME;
"""

FUNCTIONS = """
X509_NAME *X509_NAME_new(void);
void X509_NAME_free(X509_NAME *);

unsigned long X509_NAME_hash(X509_NAME *);

int i2d_X509_NAME(X509_NAME *, unsigned char **);
int X509_NAME_add_entry_by_txt(X509_NAME *, const char *, int,
                               const unsigned char *, int, int, int);
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *, int);
void X509_NAME_ENTRY_free(X509_NAME_ENTRY *);
int X509_NAME_get_index_by_NID(X509_NAME *, int, int);
int X509_NAME_cmp(const X509_NAME *, const X509_NAME *);
X509_NAME *X509_NAME_dup(X509_NAME *);
int Cryptography_X509_NAME_ENTRY_set(X509_NAME_ENTRY *);
/* These became const X509_NAME * in 1.1.0 */
int X509_NAME_entry_count(X509_NAME *);
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *, int);
char *X509_NAME_oneline(X509_NAME *, char *, int);
int X509_NAME_print_ex(BIO *, X509_NAME *, int, unsigned long);

/* These became const X509_NAME_ENTRY * in 1.1.0 */
ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *);
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *);
int X509_NAME_add_entry(X509_NAME *, X509_NAME_ENTRY *, int, int);

/* this became const unsigned char * in 1.1.0 */
int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, unsigned char *,
                               int, int, int);

/* These became const ASN1_OBJECT * in 1.1.0 */
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **,
                                               ASN1_OBJECT *, int,
                                               const unsigned char *, int);
int X509_NAME_add_entry_by_OBJ(X509_NAME *, ASN1_OBJECT *, int,
                               unsigned char *, int, int, int);

Cryptography_STACK_OF_X509_NAME *sk_X509_NAME_new_null(void);
int sk_X509_NAME_num(Cryptography_STACK_OF_X509_NAME *);
int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *);
X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int);
void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *);
int sk_X509_NAME_ENTRY_num(Cryptography_STACK_OF_X509_NAME_ENTRY *);
Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_new_null(void);
int sk_X509_NAME_ENTRY_push(Cryptography_STACK_OF_X509_NAME_ENTRY *,
                            X509_NAME_ENTRY *);
X509_NAME_ENTRY *sk_X509_NAME_ENTRY_value(
    Cryptography_STACK_OF_X509_NAME_ENTRY *, int);
Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_dup(
    Cryptography_STACK_OF_X509_NAME_ENTRY *
);
"""

CUSTOMIZATIONS = """
#if CRYPTOGRAPHY_OPENSSL_110_OR_GREATER
int Cryptography_X509_NAME_ENTRY_set(X509_NAME_ENTRY *ne) {
    return X509_NAME_ENTRY_set(ne);
}
#else
int Cryptography_X509_NAME_ENTRY_set(X509_NAME_ENTRY *ne) {
    return ne->set;
}
#endif
"""