ext/sctp/socket.c
/*
 * Transmit a message to an SCTP endpoint. The following hash of options
 * is permitted:
 *
 *  :message -> The message to send to the endpoint. Mandatory.
 *  :stream  -> The SCTP stream number you wish to send the message on.
 *  :to      -> An array of addresses to send the message to.
 *  :context -> The default context used for the sendmsg call if the send fails.
 *  :ppid    -> The payload protocol identifier that is passed to the peer endpoint. 
 *  :flags   -> A bitwise integer that contain one or more values that control behavior.
 *
 *  Note that the :to option is not mandatory in a one-to-one (SOCK_STREAM)
 *  socket connection. However, it must have been set previously via the
 *  connect method.
 *
 *  Example:
 *
 *    socket = SCTP::Socket.new
 *
 *    socket.sendmsg(
 *      :message => "Hello World!",
 *      :stream  => 3,
 *      :flags   => SCTP::Socket::SCTP_UNORDERED | SCTP::Socket::SCTP_SENDALL,
 *      :ttl     => 100,
 *      :to      => ['10.0.5.4', '10.0.6.4']
 *    )
 */
Transmit a message to an SCTP endpoint. The following hash of options
is permitted.

:message -> The message to send to the endpoint. Mandatory.
:stream  -> The SCTP stream number you wish to send the message on.
:to      -> An array of addresses to send the message to.
:context -> The default context used for the sendmsg call if the send fails.
:ppid    -> The payload protocol identifier that is passed to the peer endpoint.
:flags   -> A bitwise integer that contain one or more values that control behavior.

Note that the :to option is not mandatory in a one-to-one (SOCK_STREAM)
socket connection. However, it must have been set previously via the
connect method.






Transmit a message to an SCTP endpoint . The following hash of options is permitted . : message - > The message to send to the endpoint . Mandatory . : stream - > The SCTP stream number you wish to send the message on . : to - > An array of addresses to send the message to . : context - > The default context used for the sendmsg call if the send fails . : ppid - > The payload protocol identifier that is passed to the peer endpoint . : flags - > A bitwise integer that contain one or more values that control behavior . Note that the : to option is not mandatory in a one - to - one ( SOCK_STREAM ) socket connection . However it must have been set previously via the connect method .
static VALUE rsctp_sendmsg(VALUE self, VALUE v_options){
  VALUE v_msg, v_ppid, v_flags, v_stream, v_ttl, v_context, v_addresses;
  uint16_t stream;
  uint32_t ppid, flags, ttl, context;
  ssize_t num_bytes;
  struct sockaddr_in addrs[8];
  int sock_fd, size;
  Check_Type(v_options, T_HASH);
  bzero(&addrs, sizeof(addrs));
  v_msg       = rb_hash_aref2(v_options, "message");
  v_stream    = rb_hash_aref2(v_options, "stream");
  v_ppid      = rb_hash_aref2(v_options, "ppid");
  v_context   = rb_hash_aref2(v_options, "context");
  v_flags     = rb_hash_aref2(v_options, "flags");
  v_ttl       = rb_hash_aref2(v_options, "ttl");
  v_addresses = rb_hash_aref2(v_options, "addresses");
  if(NIL_P(v_stream))
    stream = 0;
  else
    stream = NUM2INT(v_stream);
  if(NIL_P(v_flags))
    flags = 0;
  else
    flags = NUM2INT(v_flags);
  if(NIL_P(v_ttl)){
    ttl = 0;
  }
  else{
    ttl = NUM2INT(v_ttl);
    flags |= SCTP_PR_SCTP_TTL;
  }
  if(NIL_P(v_ppid))
    ppid = 0;
  else
    ppid = NUM2INT(v_ppid);
  if(NIL_P(v_context))
    context = 0;
  else
    context = NUM2INT(v_context);
  if(!NIL_P(v_addresses)){
    int i, num_ip, port;
    VALUE v_address, v_port;
    num_ip = RARRAY_LEN(v_addresses);
    v_port = rb_hash_aref2(v_options, "port");
    if(NIL_P(v_port))
      port = 0;
    else
      port = NUM2INT(v_port);
    for(i = 0; i < num_ip; i++){
      v_address = RARRAY_PTR(v_addresses)[i];
      addrs[i].sin_family = NUM2INT(rb_iv_get(self, "@domain"));
      addrs[i].sin_port = htons(port);
      addrs[i].sin_addr.s_addr = inet_addr(StringValueCStr(v_address));
    }
    size = sizeof(addrs);
  }
  else{
    size = 0;
  }
  sock_fd = NUM2INT(rb_iv_get(self, "@sock_fd"));
  num_bytes = sctp_sendmsg(
    sock_fd,
    StringValueCStr(v_msg),
    RSTRING_LEN(v_msg),
    (struct sockaddr*)addrs,
    size,
    ppid,
    flags,
    stream,
    ttl,
    context
  );
  if(num_bytes < 0)
    rb_raise(rb_eSystemCallError, "sctp_sendmsg: %s", strerror(errno));
  return INT2NUM(num_bytes);
}
static VALUE rsctp_sendmsg ( VALUE self , VALUE v_options ) { VALUE v_msg , v_ppid , v_flags , v_stream , v_ttl , v_context , v_addresses ; uint16_t stream ; uint32_t ppid , flags , ttl , context ; ssize_t num_bytes ; struct sockaddr_in addrs [ 8 ] ; int sock_fd , size ; Check_Type ( v_options , T_HASH ) ; bzero ( & addrs , sizeof ( addrs ) ) ; v_msg = rb_hash_aref2 ( v_options , " " ) ; v_stream = rb_hash_aref2 ( v_options , " " ) ; v_ppid = rb_hash_aref2 ( v_options , " " ) ; v_context = rb_hash_aref2 ( v_options , " " ) ; v_flags = rb_hash_aref2 ( v_options , " " ) ; v_ttl = rb_hash_aref2 ( v_options , " " ) ; v_addresses = rb_hash_aref2 ( v_options , " " ) ; if ( NIL_P ( v_stream ) ) stream = 0 ; else stream = NUM2INT ( v_stream ) ; if ( NIL_P ( v_flags ) ) flags = 0 ; else flags = NUM2INT ( v_flags ) ; if ( NIL_P ( v_ttl ) ) { ttl = 0 ; } else { ttl = NUM2INT ( v_ttl ) ; flags |= SCTP_PR_SCTP_TTL ; } if ( NIL_P ( v_ppid ) ) ppid = 0 ; else ppid = NUM2INT ( v_ppid ) ; if ( NIL_P ( v_context ) ) context = 0 ; else context = NUM2INT ( v_context ) ; if ( ! NIL_P ( v_addresses ) ) { int i , num_ip , port ; VALUE v_address , v_port ; num_ip = RARRAY_LEN ( v_addresses ) ; v_port = rb_hash_aref2 ( v_options , " " ) ; if ( NIL_P ( v_port ) ) port = 0 ; else port = NUM2INT ( v_port ) ; for ( i = 0 ; i < num_ip ; i ++ ) { v_address = RARRAY_PTR ( v_addresses ) [ i ] ; addrs [ i ] . sin_family = NUM2INT ( rb_iv_get ( self , " " ) ) ; addrs [ i ] . sin_port = htons ( port ) ; addrs [ i ] . sin_addr . s_addr = inet_addr ( StringValueCStr ( v_address ) ) ; } size = sizeof ( addrs ) ; } else { size = 0 ; } sock_fd = NUM2INT ( rb_iv_get ( self , " " ) ) ; num_bytes = sctp_sendmsg ( sock_fd , StringValueCStr ( v_msg ) , RSTRING_LEN ( v_msg ) , ( struct sockaddr * ) addrs , size , ppid , flags , stream , ttl , context ) ; if ( num_bytes < 0 ) rb_raise ( rb_eSystemCallError , " " , strerror ( errno ) ) ; return INT2NUM ( num_bytes ) ; }
Transmit a message to an SCTP endpoint.
Transmit a message to an SCTP endpoint .