1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_network_io.h" 18#include "apr_errno.h" 19#include "apr_general.h" 20#include "apr_lib.h" 21#include "testutil.h" 22 23static apr_socket_t *sock = NULL; 24 25static void create_socket(abts_case *tc, void *data) 26{ 27 apr_status_t rv; 28 29 rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, 0, p); 30 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 31 ABTS_PTR_NOTNULL(tc, sock); 32} 33 34static void set_keepalive(abts_case *tc, void *data) 35{ 36 apr_status_t rv; 37 apr_int32_t ck; 38 39 rv = apr_socket_opt_set(sock, APR_SO_KEEPALIVE, 1); 40 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 41 42 rv = apr_socket_opt_get(sock, APR_SO_KEEPALIVE, &ck); 43 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 44 ABTS_INT_EQUAL(tc, 1, ck); 45} 46 47static void set_debug(abts_case *tc, void *data) 48{ 49 apr_status_t rv1, rv2; 50 apr_int32_t ck; 51 52 /* On some platforms APR_SO_DEBUG can only be set as root; just test 53 * for get/set consistency of this option. */ 54 rv1 = apr_socket_opt_set(sock, APR_SO_DEBUG, 1); 55 rv2 = apr_socket_opt_get(sock, APR_SO_DEBUG, &ck); 56 APR_ASSERT_SUCCESS(tc, "get SO_DEBUG option", rv2); 57 if (rv1 == APR_SUCCESS) { 58 ABTS_INT_EQUAL(tc, 1, ck); 59 } else { 60 ABTS_INT_EQUAL(tc, 0, ck); 61 } 62} 63 64static void remove_keepalive(abts_case *tc, void *data) 65{ 66 apr_status_t rv; 67 apr_int32_t ck; 68 69 rv = apr_socket_opt_get(sock, APR_SO_KEEPALIVE, &ck); 70 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 71 ABTS_INT_EQUAL(tc, 1, ck); 72 73 rv = apr_socket_opt_set(sock, APR_SO_KEEPALIVE, 0); 74 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 75 76 rv = apr_socket_opt_get(sock, APR_SO_KEEPALIVE, &ck); 77 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 78 ABTS_INT_EQUAL(tc, 0, ck); 79} 80 81static void corkable(abts_case *tc, void *data) 82{ 83#if !APR_HAVE_CORKABLE_TCP 84 ABTS_NOT_IMPL(tc, "TCP isn't corkable"); 85#else 86 apr_status_t rv; 87 apr_int32_t ck; 88 89 rv = apr_socket_opt_set(sock, APR_TCP_NODELAY, 1); 90 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 91 92 rv = apr_socket_opt_get(sock, APR_TCP_NODELAY, &ck); 93 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 94 ABTS_INT_EQUAL(tc, 1, ck); 95 96 rv = apr_socket_opt_set(sock, APR_TCP_NOPUSH, 1); 97 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 98 99 rv = apr_socket_opt_get(sock, APR_TCP_NOPUSH, &ck); 100 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 101 ABTS_INT_EQUAL(tc, 1, ck); 102 103 rv = apr_socket_opt_get(sock, APR_TCP_NODELAY, &ck); 104 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 105 /* TCP_NODELAY is now in an unknown state; it may be zero if 106 * TCP_NOPUSH and TCP_NODELAY are mutually exclusive on this 107 * platform, e.g. Linux < 2.6. */ 108 109 rv = apr_socket_opt_set(sock, APR_TCP_NOPUSH, 0); 110 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 111 112 rv = apr_socket_opt_get(sock, APR_TCP_NODELAY, &ck); 113 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 114 ABTS_INT_EQUAL(tc, 1, ck); 115#endif 116} 117 118static void close_socket(abts_case *tc, void *data) 119{ 120 apr_status_t rv; 121 122 rv = apr_socket_close(sock); 123 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 124} 125 126abts_suite *testsockopt(abts_suite *suite) 127{ 128 suite = ADD_SUITE(suite) 129 130 abts_run_test(suite, create_socket, NULL); 131 abts_run_test(suite, set_keepalive, NULL); 132 abts_run_test(suite, set_debug, NULL); 133 abts_run_test(suite, remove_keepalive, NULL); 134 abts_run_test(suite, corkable, NULL); 135 abts_run_test(suite, close_socket, NULL); 136 137 return suite; 138} 139 140